I want to have the exact distance between the Y-coordinate of an element an the Y-value=0, which I consider as the top of the document.
myElement.getBoundingClientRect().top;
But the value of getBoundingClientRect() seems to change while scrolling. How can I get the real distance between myElement and the Y-coordinate=0 (top of document)?
getBoundingClientRect needs a bit more care to avoid bugs in scrollY/pageYOffset:
The bugs to avoid are:
scrolling in Android Chrome since Chrome Mobile 43 has wrong values for scrollY/pageYOffset (especially when the keyboard is showing and you scroll).
Pinch-zoom in Microsoft IE or Edge causes wrong values for scrollY/pageYOffset.
Some (obsolete) browsers don't have a height/width e.g. IE8
Edit: The above code can be simplified a lot by just using
document.body.getBoundingClientRect()
instead of adding a div - I haven't tried it though so I am leaving my answer as it stands. Also the body needsmargin:0
(reset.css usually does this). This answer simplifies the code down a lot, while still avoiding the bugs in jQuery.offset()!Edit 2: Chrome 61 introduced
window.visualViewport
to give correct values for the actual viewport which is probably another way to fix issues; but beware that Android Chrome 66 was still buggy ifSettings -> Accessability -> Force enable zoom
was ticked (bugs with orientation change, focused inputs, absolutely positioned popup wider than viewport).It is because
getBoundingClientRect()
gets values with respect to thewindow
(only the current visible portion of the page), not thedocument
(whole page).Hence, it also takes scrolling into account when calculating its values
Basically,
document = window + scroll
So, to get the distance between myElement and the Y-coordinate=0 (top of document), you would have add the value of vertical-scroll also:
myElement.getBoundingClientRect().top + window.scrollY;
Source: https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect