To get the top, you need to add the offsetTop element and the element offsetParent offsetTop . Do this before the DOM to document . This explains the absolute, relative and fixed positioning. To the left, do the same with offsetLeft .
These two functions add two properties to the Element , documentOffsetTop and documentOffsetLeft , which will receive the top / left side of any element:
window.Object.defineProperty( Element.prototype, 'documentOffsetTop', { get: function () { return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop : 0 ); } } ); window.Object.defineProperty( Element.prototype, 'documentOffsetLeft', { get: function () { return this.offsetLeft + ( this.offsetParent ? this.offsetParent.documentOffsetLeft : 0 ); } } );
This demo shows several combinations of layout elements by comparing documentOffsetTop with jQuery offset().top .
Demo: http://jsfiddle.net/ThinkingStiff/3G7EZ/
Script:
window.Object.defineProperty( Element.prototype, 'documentOffsetTop', { get: function () { return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop : 0 ); } } ); var line = document.getElementsByClassName( 'grid-line' )[0], grid = document.getElementById( 'grid' ); for( var index = 2; index < 100; index++ ) { var copy = line.cloneNode(); copy.textContent = ( index * 10 ); grid.appendChild( copy ); }; var offset = document.getElementById( 'absolute' ); offset.textContent = 'absolute: ' + offset.documentOffsetTop + ', $' + $( offset ).offset().top; offset = document.getElementById( 'static' ); offset.textContent = 'static: ' + offset.documentOffsetTop + ', $' + $( offset ).offset().top; offset = document.getElementById( 'static2' ); offset.textContent = 'static: ' + offset.documentOffsetTop + ', $' + $( offset ).offset().top; offset = document.getElementById( 'relative' ); offset.textContent = 'relative: ' + offset.documentOffsetTop + ', $' + $( offset ).offset().top; offset = document.getElementById( 'fixed-side' ); offset.textContent = 'fixed/absolute (side): ' + offset.documentOffsetTop + ', $' + $( offset ).offset().top; offset = document.getElementById( 'fixed-top' ); offset.textContent = 'fixed/absolute (top): ' + offset.documentOffsetTop + ', $' + $( offset ).offset().top; offset = document.getElementById( 'fixed-bottom' ); offset.textContent = 'fixed/absolute (bottom): ' + offset.documentOffsetTop + ', $' + $( offset ).offset().top; offset = document.querySelectorAll( '#relative-wrapped-absolute div' )[0]; offset.textContent = 'absolute/relative/static (absolute/relative wrapped): ' + offset.documentOffsetTop + ', $' + $( offset ).offset().top; offset = document.querySelectorAll( '#static-wrapped-static div' )[0]; offset.textContent = 'static (static wrapped): ' + offset.documentOffsetTop + ', $' + $( offset ).offset().top;
HTML:
<div id="static" class="offset">0</div> <div id="static2" class="offset">0</div> <div id="static-wrapped-static"><br /><div class="offset">0</div></div> <div id="absolute" class="offset">0</div> <div id="relative" class="offset">0</div> <div id="fixed-side" class="offset">0</div> <div id="fixed-top" class="offset">0</div> <div id="fixed-bottom" class="offset">0</div> <div style="position: relative;"><div id="relative-wrapped-absolute"><div class="offset">0</div></div></div> <div id="grid"><div class="grid-line">10</div></div>
CSS
body {padding-left: 12px;} #absolute { top: 100px; position: absolute; } #relative { top: 150px; position: relative; } #fixed-side { right: 0; position: fixed; } #fixed-top { left: 50%; position: fixed; top: 0; } #fixed-bottom { left: 50%; position: fixed; bottom: 0; } #relative-wrapped-absolute { top: 8px; position: relative; } #relative-wrapped-absolute div { position: absolute; top: 20px; } .offset { border: 1px solid black; } #grid { height: 100%; left: 0; position: absolute; top: 1px; width: 100%; z-index: -1; } .grid-line { border-bottom: 1px solid lightgray; font-size: 8px; height: 9px; line-height: 20px; }
Output:
