Search code examples
javascriptjqueryposition

How do I get the actual values for left/right/top/bottom of an absolutely positioned element?


(This seems like a simple question that would have been asked before, but if it has I can't find it, though there are lots of similar ones that don't answer what I want.)

In Firefox (24.0), this code gives me what I want - the relevant number of pixels:

jQuery('selector').css('right')

In Chrome (34.0.1847.137 m), it only gives pixels for left/top but returns auto for right/bottom.

There are various questions on SO explaining that this is the expected behaviour of .css, but I cannot find anything that explains how to get my desired behaviour - i.e. give me calculated pixel values for all four values.

Do JS or jQuery have any way to directly get these four values, that works consistently in all browsers/scenarios? (Or do I have to resort to ugly manual calculations?)

Clarification:
I need values that are equivalent to the .css('right') values that Firefox returns - which is the distance between the right-edges of the current and parent element. This is not the same as viewport-relative left+width definitions which some functions return.

i.e. the logged values here should be numerically the same:

elem = jQuery('selector')
rect = someFunction( elem[0] );
console.log([ elem.css('left') , rect.left ]);
console.log([ elem.css('right') , rect.right ]);
console.log([ elem.css('top') , rect.top ]);
console.log([ elem.css('bottom') , rect.bottom ]);

Unless I'm misreading the other answers, only kalley's getRelativeClientRect answer meets this criteria.


Solution

  • you can use getBoundingClientRect. It will take into account any transforms as well, if you are using them.

    You'd need to call it like jQuery('selector')[0].getBoundingClientRect(). Or use vanilla javascript like document.querySelector('selector').getBoundingClientRect(), which will return a single element or document.querySelectorAll('selector')[index].getBoundingClientRect().

    To summarize, in a slightly more readable format:

    • jQuery('selector')[0].getBoundingClientRect()
    • document.querySelector('selector').getBoundingClientRect()
    • document.querySelectorAll('selector')[index].getBoundingClientRect()

    or replace the QS calls with older ones like getElementById, etc.

    Here's a function you could use if you wanted to get it relative to it's parent:

    function getRelativeClientRect(el) {
      var rect = el.getBoundingClientRect(),
          parentRect = el.offsetParent.getBoundingClientRect();
      return {
        bottom: parentRect.bottom - rect.bottom,
        height: rect.height,
        left: rect.left - parentRect.left,
        right: parentRect.right - rect.right,
        top: rect.top - parentRect.top,
        width: rect.width
      };
    }