Use boundingClientRect to get an element's position
To get an HTML element's position, use boundingClientRect()
. This function returns the top
, left
, bottom
, and right
values, along with a few others. These positions are relative to the viewport.
const boundingClientRect = document.querySelector(...).getBoundingClientRect();
boundingClientRect.left;
boundingClientRect.right;
boundingClientRect.top;
boundingClientRect.bottom;
The viewport
The viewport takes the scroll positions and any iframes into account. As a result, if the window or any elements in it are scrolled, the positions returned from the function changes.
This means that getBoundingClientRect()
returns the position the user sees the element. Due to this fact, the top/left can easily go negative.
To the document
To get the coordinates relative to the document instead of the viewport, add the scroll positions of all the ancestors:
const calculateScroll = (e) => {
if (e) {
const [scrollTop, scrollLeft] = calculateScroll(e.parentNode);
return [(e.scrollTop || 0) + scrollTop, (e.scrollLeft || 0) + scrollLeft];
}else {
return [0, 0];
}
};
And finally, add the scrollTop
/scrollLeft
to the coordinates:
boundingClientRect.top + scrollTop
boundingClientRect.bottom + scrollTop
boundingClientRect.left + scrollLeft
boundingClientRect.right + scrollLeft
These coordinates are now relative to the document, so scrolling any of the element's parents won't change them.