jQuery API

.position()

.position() Returns: Object

Description: Get the current coordinates of the first element in the set of matched elements, relative to the offset parent.

  • version added: 1.2.position()

The .position() method allows us to retrieve the current position of an element relative to the offset parent. Contrast this with .offset(), which retrieves the current position relative to the document. When positioning a new element near another one and within the same containing DOM element, .position() is the more useful.

Returns an object containing the properties top and left.

Note: jQuery does not support getting the position coordinates of hidden elements or accounting for borders, margins, or padding set on the body element.

Example:

Access the position of the second paragraph:

<!DOCTYPE html>
<html>
<head>
  <style>

  div { padding: 15px;}
  p { margin-left:10px; }
  </style>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
  
<div>
  <p>Hello</p>
</div>
<p></p>

<script>
var p = $("p:first");
var position = p.position();
$("p:last").text( "left: " + position.left + ", top: " + position.top );
</script>

</body>
</html>

Demo:

Support and Contributions

Need help with .position() or have a question about it? Visit the jQuery Forum or the #jquery channel on irc.freenode.net.

Think you've discovered a jQuery bug related to .position()? Report it to the jQuery core team.

Found a problem with this documentation? Report it on the GitHub issue tracker

  • Alejo

    I have a problem with .position() in Google Chrome.

    It may sound weird, but when browsing with Google Chrome, .position().left doesn’t returns the actual X position of an element. I have a DIV:

    #imgCont
    {
    margin: auto;
    width: 50%;
    height: 300px;
    background-color: #408080;
    }

    When browsing with Firefox or IE, .position().left returns ~= 260, but Google Chrome returns 8! The curious thing is that .position().top works great. Any ideas?

    (excuse my poor english)

    • http://www.learningjquery.com/ Karl Swedberg

      Please report bugs to the appropriate jQuery forum

    • smnh

      The Problem:
      This happens because when specifying margin:auto, Chrome (and also Safari, as they both use WebKit) sets computed value of margin-left and margin-right to an equal sized used values. While Firefox and IE sets computed value of margin-left and margin-right to 0px. So if you have a 1000px wide page and your element takes 50% width (i.e.: 500px) and has margin:auto, then Chrome will set element’s computed value of margin-left and margin-right to 250px (so it fills all the empty space between element’s border edge and its parent element’s content edge with margins and by so horizontally centers the element). However, Firefox and IE will set computed value of margin-left and margin-right to 0px, so there is no margins between the element’s border edge and its parent element’s content edge but it is still centered. You can actually see it happening using Firebug in Firefox and Developer Tools in Chrome. In depth explanation can be found here: http://www.3d3r.com/simon/marginAutoComputedValue

      Now, because jQuery computes element’s .position() from its margin edges, we have differences between Chrome and Firefox. Firefox computes .position().left from the left edge of the element without any additional margins because its margin-left computed value is 0px. Therefore, Firefox gets the proper .position().left value. On the other hand, Chrome, computes .position().left from the left margin edge which is the same as the content edge of its parent element, which happens to be your body element. Therefore, there is exactly 0px between left margin edge of the centered element and body’s content edge. The 8px you get is probably because your body has 8px margin (this is the default body margin in Chrome).

      Solution:
      I think the simplest solution will be is to include additional div element inside #imgCont element and to use .position().left on this div.

      #imgCont {
      margin: auto;
      width: 50%;
      height: 300px;
      background-color: #408080;
      }

      Hello World

      alert($(“#imgCont > div”).position().left);

    • http://pulse.yahoo.com/_263BSING2PB26LPBPLOYSLFGFU serkan

      “position.left + 0″ works for me

  • Anonymous

    i have the same .position().left problem. when i alert the value, it returns 0 with on chrome. with other browsers it return actual number. does anybody have an idea why this happens?

    • http://www.learningjquery.com/ Karl Swedberg

      You’re much more likely to find an answer to your question on the jQuery Forum.

    • Mr. CoolJay

      I ran into this problem, but an easy fix is

      var leftPos = parseFloat($(this).css(‘left’));

      and you can do the same thing for what ever else too.

    • aurelio

      Use css.offset().left. It works fine (teste with Chrome & safari).

      The solution of Mr Cooljay
      var leftPos = parseFloat($(this).css(‘left’));
      don’t works for element not with absolure positioning, returning ‘auto’ as value failing the parseFloat.

      regards

    • http://ianbarker.myopenid.com/ Ian Barker

      I found this issue with floated elements in chrome, however I found that if you set a width and height on the floated element then it will work as expected.

  • Pipeman

    Does position.left work with inline-block elements? I’m getting 0.

  • http://ajaho.com/ Ajaho

    This plugin function fixes problems with wrong position in Chrome

    jQuery.fn.aPosition = function() {
    thisLeft = this.offset().left;
    thisTop = this.offset().top;
    thisParent = this.parent();
    parentLeft = thisParent.offset().left;
    parentTop = thisParent.offset().top;
    return {
    left: thisLeft-parentLeft,
    top: thisTop-parentTop
    }
    }

    • 2pha

      it doesn't seem to fix it if the margin is auto

      • 2pha

        because I had a margin:auto on the above that too. :(
        I ended up just using something like this for what I needed.
        ($(this).parent().width() – $(this).width()) / 2

  • smnh

    Sometimes you want to get coordinates not relative to an offset parent but relative to some offset ancestor. Here is a script that extends jQuery with a .offsetAncestor method. This method takes selector as an argument and finds coordinates to the closest offset ancestor which is positioned and matches that selector.

    /** * Get the current coordinates of the first element in the set of matched * elements, relative to the closest positioned ancestor element that * matches the selector. * @param {String} selector */jQuery.fn.offsetAncestor = function(selector) {    var left = 0;    var top = 0;    this.each(function(index, element) {        // check if current element has an ancestor matching a selector        var $matchedAncestor = jQuery(this).closest(selector);        if ($matchedAncestor.length) {            // check if the ancestor is positioned            if ($matchedAncestor.css("position") !== "static") {                var $child = jQuery(this);                // traverse all the way up and accumulate offsets until we                // get to the matched ancestor                while ($child.get(0) !== $matchedAncestor.get(0)) {                    left += $child.position().left;                    top += $child.position().top;                    $child = $child.offsetParent();                }                // we have found the ancestor and computed the offset                // stop iterating                return false;            }        }    });    return {        left:    left,        top:    top    }};

    Example:

    <div id="ancestor" style="position:relative; padding-left:10px;">    I am positioned offset ancestor    <div id="parent" style="position:relative; padding-left:10px;">        I am positioned offset parent        <div id="child">            I am a child        </div>    </div></div><script>    var $child = $('#child');    alert("$('#child').position() = {" +          "left:" + $child.position().left +  "," +          "top:" + $child.position().top + "}n" +          "$('#child').offsetAncestor('#parent') = {" +          "left:" +$child.offsetAncestor("#parent").left + "," +          "top:" + $child.offsetAncestor("#parent").top + "}n" +          "$('#child').offsetAncestor('#ancestor') = {" +          "left:" +$child.offsetAncestor("#ancestor").left + "," +          "top:" + $child.offsetAncestor("#ancestor").top + "}");</script>
    • Antonin B

      hello,
      for parseInt ($ ancestor.css (“borderLeftWidth”), 10) and parseInt ($ ancestor.css (“borderTopWidth”), 10);

      my FF and IE 7 returns 0px look back “medium”, then NaN

  • Dave P

    Having some trouble getting position(), offset() or even width() of a link, keep getting 0 or auto. Not sure what i’m doing wrong?

    The hashtag of the URL contains the link HREF ID. I’m grabbing that and trying to do some animation using the width of the link.Here’s a cut down example:

    jq which returns ’0′ or auto,

    var idHash = location.hash;

    var sel = $j(‘a[href='+idHash+']‘).width();
    var sel = $j(‘a[href='+idHash+']‘).offset().left;
    var sel = $j(‘a[href='+idHash+']‘).position().left;

    HTML snippet (the list items are floated left with a text-indent):

    Comp1
    Comp2

    Have tried removing all styling and still returns 0 and auto.

    • GGGG

      sdgsdfgsdfgs

      • das;dk;as

        sfgdsfasfsf

  • Aladjev Andrew

    position.left() and css(“left”) in opera for img I take wrong integer
    opera dragonfly sad me that left = 492
    but position.left() = css(“left”) = 501

  • http://jtsnake.myopenid.com/ Jake

    Also note that .position(), as with .offset(), does not work on hidden elements.

    • Reaktor8

      Good point… so whats the alternative on working with hidden elements (ie. developer doesn't want to display element while changing its position?)

      • ReinVO

        position() only GETS the position, it does not SET it. For setting the position on hidden elements you could use css or the css-function.

  • Jay King

    what’s the difference between .position() and .offset() ? I am confused about it !

    • Ryan

      .offset() uses the entire window, whereas .position() uses the parent

      • Jay King

        .offset() uses the entire window, whereas .position() uses the parent . and what's the parent of window ?

        • K. Shahzad

          Its not the parent of window but its parent of current element. e.g. if a paragraph tag is within a div tag then the div is parent of paragraph tag. Hope this helps.

        • Nathan S.

          Not the parent of the window the parent of the object on which you're calling .position()

      • Blaine Simpson

        That is a bad description. .offset() is not positioned according to the “window” but according to the entire document, just as it says above. One could consider this document view as a virtual window, but saying that it “uses the entire window” really implies that it is positioned according to the browser window that you see, and that is something entirely different– i.e. “fixed” positioning.

  • Antonin B

    hello,
    for parseInt ($ ancestor.css (“borderLeftWidth”), 10) and parseInt ($ ancestor.css (“borderTopWidth”), 10);

    my FF and IE 7 returns 0px look back “medium”, then NaN

  • Antonin B

    hello,
    for parseInt ($ ancestor.css (“borderLeftWidth”), 10) and parseInt ($ ancestor.css (“borderTopWidth”), 10);

    my FF and IE 7 returns 0px look back “medium”, then NaN

  • Antonin B

    hello,
    for parseInt ($ ancestor.css (“borderLeftWidth”), 10) and parseInt ($ ancestor.css (“borderTopWidth”), 10);

    my FF and IE 7 returns 0px look back “medium”, then NaN

  • Antonin B

    hello,
    for parseInt ($ ancestor.css (“borderLeftWidth”), 10) and parseInt ($ ancestor.css (“borderTopWidth”), 10);

    my FF and IE 7 returns 0px look back “medium”, then NaN

  • Antonin B

    hello,
    for parseInt ($ ancestor.css (“borderLeftWidth”), 10) and parseInt ($ ancestor.css (“borderTopWidth”), 10);

    my FF and IE 7 returns 0px look back “medium”, then NaN

  • Antonin B

    hello,
    for parseInt ($ ancestor.css (“borderLeftWidth”), 10) and parseInt ($ ancestor.css (“borderTopWidth”), 10);

    my FF and IE 7 returns 0px look back “medium”, then NaN

  • Antonin B

    hello,
    for parseInt ($ ancestor.css (“borderLeftWidth”), 10) and parseInt ($ ancestor.css (“borderTopWidth”), 10);

    my FF and IE 7 returns 0px look back “medium”, then NaN

  • Antonin B

    hello,
    for parseInt ($ ancestor.css (“borderLeftWidth”), 10) and parseInt ($ ancestor.css (“borderTopWidth”), 10);

    my FF and IE 7 returns 0px look back “medium”, then NaN

  • Nathan S.

    Not the parent of the window the parent of the object on which you're calling .position()

  • Premsonbaby
  • Mustafa

    How would you go about getting the 'right' attribute or position in jquery?

    • Serdar

      var elementRight = $(“#element”).attr(“right”);

  • Ian OSullivan

    When I resize the window the position is not positioning relative to the parent element but to the window. How do I fix this