Finding element's position relative to the document

JavascriptDom

Javascript Problem Overview


What's the easiest way to determine an elements position relative to the document/body/browser window?

Right now I'm using .offsetLeft/offsetTop, but this method only gives you the position relative to the parent element, so you need to determine how many parents to the body element, to know the position relaltive to the body/browser window/document position.

This method is also to cumbersome.

Javascript Solutions


Solution 1 - Javascript

You can get top and left without traversing DOM like this:

function getCoords(elem) { // crossbrowser version
    var box = elem.getBoundingClientRect();
    
    var body = document.body;
    var docEl = document.documentElement;
    
    var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
    var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
    
    var clientTop = docEl.clientTop || body.clientTop || 0;
    var clientLeft = docEl.clientLeft || body.clientLeft || 0;
    
    var top  = box.top +  scrollTop - clientTop;
    var left = box.left + scrollLeft - clientLeft;
    
    return { top: Math.round(top), left: Math.round(left) };
}

Solution 2 - Javascript

You can use element.getBoundingClientRect() to retrieve element position relative to the viewport.

Then use document.documentElement.scrollTop to calculate the viewport offset.

The sum of the two will give the element position relative to the document:

element.getBoundingClientRect().top + document.documentElement.scrollTop

Solution 3 - Javascript

You can traverse the offsetParent up to the top level of the DOM.

function getOffsetLeft( elem )
{
    var offsetLeft = 0;
    do {
      if ( !isNaN( elem.offsetLeft ) )
      {
          offsetLeft += elem.offsetLeft;
      }
    } while( elem = elem.offsetParent );
    return offsetLeft;
}

Solution 4 - Javascript

I've found the following method to be the most reliable when dealing with edge cases that trip up offsetTop/offsetLeft.

function getPosition(element) {
    var clientRect = element.getBoundingClientRect();
    return {left: clientRect.left + document.body.scrollLeft,
            top: clientRect.top + document.body.scrollTop};
}

Solution 5 - Javascript

I suggest using

element.getBoundingClientRect()

as proposed here instead of manual offset calculation through offsetLeft, offsetTop and offsetParent. as proposed here Under some circumstances* the manual traversal produces invalid results. See this Plunker: http://plnkr.co/pC8Kgj

*When element is inside of a scrollable parent with static (=default) positioning.

Solution 6 - Javascript

document-offset (3rd-party script) is interesting and it seems to leverage approaches from the other answers here.

Example:
var offset = require('document-offset')
var target = document.getElementById('target')
console.log(offset(target))
// => {top: 69, left: 108} 

Solution 7 - Javascript

For those that want to get the x and y coordinates of various positions of an element, relative to the document.

const getCoords = (element, position) => {
  const { top, left, width, height } = element.getBoundingClientRect();
  let point;
  switch (position) {
    case "top left":
      point = {
        x: left + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "top center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "top right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + window.pageYOffset
      };
      break;
    case "center left":
      point = {
        x: left + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "center right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + height / 2 + window.pageYOffset
      };
      break;
    case "bottom left":
      point = {
        x: left + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
    case "bottom center":
      point = {
        x: left + width / 2 + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
    case "bottom right":
      point = {
        x: left + width + window.pageXOffset,
        y: top + height + window.pageYOffset
      };
      break;
  }
  return point;
};

Usage

  • getCoords(document.querySelector('selector'), 'center')

  • getCoords(document.querySelector('selector'), 'bottom right')

  • getCoords(document.querySelector('selector'), 'top center')

Solution 8 - Javascript

If you don't mind using jQuery, then you can use offset() function. Refer to documentation if you want to read up more about this function.

Solution 9 - Javascript

http://www.quirksmode.org/js/findpos.html Explains the best way to do it, all in all, you are on the right track you have to find the offsets and traverse up the tree of parents.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioneinsteinView Question on Stackoverflow
Solution 1 - JavascriptbasilView Answer on Stackoverflow
Solution 2 - Javascriptdy_View Answer on Stackoverflow
Solution 3 - JavascriptKeatsKelleherView Answer on Stackoverflow
Solution 4 - JavascriptRobin StewartView Answer on Stackoverflow
Solution 5 - JavascriptHANiSView Answer on Stackoverflow
Solution 6 - JavascriptMathieu M-GosselinView Answer on Stackoverflow
Solution 7 - JavascriptRaphael RafatpanahView Answer on Stackoverflow
Solution 8 - JavascriptAdamView Answer on Stackoverflow
Solution 9 - JavascriptJake KalstadView Answer on Stackoverflow