jQuery API

.offset()

Contents:

.offset() Returns: Object

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

  • version added: 1.2.offset()

The .offset() method allows us to retrieve the current position of an element relative to the document. Contrast this with .position(), which retrieves the current position relative to the offset parent. When positioning a new element on top of an existing one for global manipulation (in particular, for implementing drag-and-drop), .offset() is the more useful.

.offset() returns an object containing the properties top and left.

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

While it is possible to get the coordinates of elements with visibility:hidden set, display:none is excluded from the rendering tree and thus has a position that is undefined.

Examples:

Example: Access the offset of the second paragraph:

<!DOCTYPE html>
<html>
<head>
  <style>
p { margin-left:10px; }
  </style>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
  <p>Hello</p><p>2nd Paragraph</p>
<script>var p = $("p:last");
var offset = p.offset();
p.html( "left: " + offset.left + ", top: " + offset.top );</script>

</body>
</html>

Demo:

Example: Click to see the offset.

<!DOCTYPE html>
<html>
<head>
  <style>
p { margin-left:10px; color:blue; width:200px; 
    cursor:pointer; }
span { color:red; cursor:pointer; }
div.abs { width:50px; height:50px; position:absolute;
          left:220px; top:35px; background-color:green; 
          cursor:pointer; }
  </style>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
  <div id="result">Click an element.</div>
<p>
  This is the best way to <span>find</span> an offset.
</p>

<div class="abs">
</div>
  
<script>
$("*", document.body).click(function (e) {
  var offset = $(this).offset();
  e.stopPropagation();
  $("#result").text(this.tagName + " coords ( " + offset.left + ", " +
                                  offset.top + " )");
});

</script>

</body>
</html>

Demo:

.offset( coordinates ) Returns: jQuery

Description: Set the current coordinates of every element in the set of matched elements, relative to the document.

  • version added: 1.4.offset( coordinates )

    coordinatesAn object containing the properties top and left, which are integers indicating the new top and left coordinates for the elements.

  • version added: 1.4.offset( function(index, coords) )

    function(index, coords)A function to return the coordinates to set. Receives the index of the element in the collection as the first argument and the current coordinates as the second argument. The function should return an object with the new top and left properties.

The .offset() setter method allows us to reposition an element. The element's position is specified relative to the document. If the element's position style property is currently static, it will be set to relative to allow for this repositioning.

Example:

Set the offset of the second paragraph:

<!DOCTYPE html>
<html>
<head>
  <style>p { margin-left:10px; } </style>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
  <p>Hello</p><p>2nd Paragraph</p>
<script>$("p:last").offset({ top: 10, left: 30 });</script>

</body>
</html>

Demo:

Support and Contributions

Need help with .offset() 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 .offset()? Report it to the jQuery core team.

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

  • http://zachrose.info/ Zach

    Once the position of an element has been changed with offset(coordinates), is there a way to “let go” of the element and put it back where it would naturally wind up?

    I’m working on something that dynamically repositions things. I’d like to be able to reset and then reapply the positioning when the window is resized.

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

      Since .offset(coords) sets the top and left style properties, you could probably “release” the positioning by doing something like this:
      $('myelement').css({top: '', left: ''});

    • Peter

      You could save the offset object by first calling it without any parameters, and then use that object to reset it.

      var myOffset = $(‘#elementId’).offset();
      // reposition however you want, then reset by:
      $(‘#elementId’).offset(myOffset);

      • Anonymous

        I try this just a moment, but I found that the top value is not correct, I got “800″ for myOffset.top, but when I reset it, the top value is 500.

        • Peter

          I have noticed that it doesn’t behave properly when you’ve changed the dimensions of the body element. For example, it wasn’t behaving as expected when I had the css:

          body { width: 900px; }

          Once I removed this, and instead used a div to accomplish the same thing, it worked well.

          css:
          body>div { width: 900px; }

          html:

  • Timothy Wall

    I don't see any mention of the defined behavior when .offset() is applied to an element within an iframe. I currently see (with 1.4.2) that the offset returned is relative to the containing iframe. Is the containing iframe considered the “document” in this case?

    • http://www.mobify.me John Boxall

      The offset returned is calculated relative to the document jQuery was loaded in. So if you ask for the offset of an element inside an iframe from the parent document, offset will return the combined offsets of both documents.

  • http://www.wantsa.com Earl

    It's worth noting that, in IE only, if you only provide a “top” value for the offset, an error occurs. Consider this code:

    $('my_elem').offset({top: 100});

    In FF, Chrome and Safari, this does exactly what you expect: moves my_elem vertically to 100px from the top, without changing the horizontal positioning. In IE, this causes an error.

    As it turns out, IE looks at the undefined “left” value, and stringifies it to “NaN”. This means that the jQuery offset() code tries to do something like this:

    my_elem.style.left = “NaNpx”;

    Thus, the error.

    To resolve this problem, be sure to provide a “left” value in your offset() call. If you want to retain the current “left” value, you could do this:

    var my_elem_offset = $('my_elem').offset();

    my_elem_offset.top = 100;
    $('my_elem').offset(my_elem_offset);

  • Cui Jiajun

    try to add below script
    $(“p:last”).offset(function(index,coords){
    alert(index);
    alert(coords.left);
    });
    ,IE simply raises Error such as “'top' is null or not an object”

    Don't know what's wrong

    • http://billybobsbibleblog.blogspot.com/ billybobbibb

      The problem is that the function inside offset() must return an anonymous object that evaluates to a “position”, i.e.:

      $(“p:last”).offset(function(index, coords) {
      alert(index);
      alert(coords.left);
      return {left: 999, top:999}; //<– you need to return this.
      });

  • Cui Jiajun

    try to add below script
    $(“p:last”).offset(function(index,coords){
    alert(index);
    alert(coords.left);
    });
    ,IE simply raises Error such as “'top' is null or not an object”

    Don't know what's wrong

  • Pablo Ziliani

    I was having trouble setting the position of a body's child element using offset() on IE (any version), I haven't delved much into it, but the effect was like it *sometimes* added some extra value to the left and to the top (the actually numbers were 1024 and 256, if I remember correctly… not sure if this has any further meaning).

    I managed to work it around using .css({top: $foo, left: $bar}), but it worked only because the body happens to be also the offset parent.

  • Anna

    The first example says “left: 10, top: 50″ which is obviously relative to the container, not the document. Using Safari on Mac.

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

      It's relative to the document within the iframe.

  • Anna

    The first example says “left: 10, top: 50″ which is obviously relative to the container, not the document. Using Safari on Mac.

  • Anna

    The first example says “left: 10, top: 50″ which is obviously relative to the container, not the document. Using Safari on Mac.

  • http://vikku.info Jayapal Chandran

    How to find the offset of an object reference instead of using '#id' to find an elements offset?
    Like…

    onclick = “show(this)”

    function show(src)
    {
    var pos = $(src).offset()
    alert(pos.left)// which gave a long factional value
    }

    is that right?
    do we have to parseInt the value to get the integer part

  • Chris Shireman

    I have a slide show function that displaying div layers over top of each other. The position of the next slide is determined using a div layer that provides the anchor point for the slide show. When I scroll down the page, the offset function returns the coordinate of the anchor div relative to the window coordinate system. When I set the coordinate though, it changes it's position relative to the document coordinate system. The effect is that as I scroll down the page, the slide show starts moving up the page. This is only happening in internet explorer, not firefox or chrome. Also, it behaves differently on another site where the same script is running – it reports and sets the coordinates correctly. The only difference I can see is in the structure of the pages. The site that works has the slide show 2 levels deep inside nested div tags, which the one that doesn't has the slide show at 5 levels deep. I know IE has trouble handling div tags more than three levels deep, could that be it?

  • Anon

    Note: elem.offset({top: 100, left: 100}) does not work if elem is not visible (i.e. display:none). If you want to position an element just prior to showing the element, you have to call elem.css(“top”, “100px”).css(“top”, “100px”).show();

  • Anon

    Correction:

    elem.css(“top”, “100px”).css(“left”, “100px”).show();

    • Pablo Ziliani

      …which is basically a slightly suboptimal version of elem.css({top: 100, left: 100}).show(), or even elem.css({top: 100, left: 100, display: “block”}) (assuming you deal with a block-level element).

      Note that there's no need to make an element visible just to set its position (not that you suggested that, just saying).

      If you want to put a hidden element at (100,100) on the page, a safer substitute for offset() would be something like:

      var parent_offset = elem.offsetParent().offset();
      elem.css({left: 100-parent_offset.left, top: 100-parent_offset.top});

      (also, make sure your element's margin is 0 or you'll get weird results, particularly if it's “auto”)

      • Guest

        Ấn nhầm nút Liked!

  • Hiller

    Not work if parents of current element have padding, margin and absolutle position. Can help?
    Maybe i somesing loose or don't understand…

  • Vijay

    offset().top always returns null or not an object in IE as well as Firefox browser. I am tying to do this using jquery plugin jnice. To be prceise this shows me error occured at line 148.
    I am inserting select box in the UI. Any help in this regards would be appreciated

  • Albanx

    I want to report a bug: when I get the offset of some relativ DIV, the offset.top returns the div width not the real offset: $(somediv).offset().top doesnt give the real top but give width? is this a bug of jquery.js 1.4.4

  • http://twitter.com/eveevans eveevans

    If you want the value (top or left) from the offset, You have to write something like:
    $(“ElementID”).offset().top
    or
    $(“ElementID”).offset().left

  • http://twitter.com/eveevans eveevans

    If you want the value (top or left) from the offset, You have to write something like:
    $(“ElementID”).offset().top
    or
    $(“ElementID”).offset().left

  • liv913

    Hi guys,

    running Firebug.Console.log(this.$element.offset()), I see that offset() return a different top value every time that page is scrolled up or down; why isn't it returning always the same value?

  • Andreas Olsson

    offset() returns wrong top and left values in IE7 after page i scrolled.

    When I have a scrolled down page in IE7 and call offset() on an element the returned value for top is too small. If I add document.documentElement.scrollTop to the value of top I get the correct position.

    Is this a bug in jquery (using jquery-1.4.1) or have I got something wrong?

  • http://twitter.com/vandalk Daniel Queiroz Porto

    Hello! I'm new to jquery and javascript, and to web site developing overall, and I'm having a problem with this function. I have the following code working fine on chrome and FF but not working on IE:

    $(document).keydown(function(k){
    var keycode=k.which;
    var posk=$('html').offset();
    var centeryk=screen.availHeight*0.4;
    var centerxk=screen.availWidth*0.4;
    $(“span”).text(k.which+”,”+posk.top+”,”+posk.left);
    if (keycode==37){
    k.preventDefault();
    $(“html,body”).stop().animate({scrollLeft:-1*posk.left-centerxk})
    };
    if (keycode==38){
    k.preventDefault();
    $(“html,body”).stop().animate({scrollTop:-1*posk.top-centeryk})
    };
    if (keycode==39){
    k.preventDefault();
    $(“html,body”).stop().animate({scrollLeft:-1*posk.left+centerxk})
    };
    if (keycode==40){
    k.preventDefault();
    $(“html,body”).stop().animate({scrollTop:-1*posk.top+centeryk})
    };
    });

    what I want it to do is to scroll the window a set percentage using the arrow keys, so my thought was to find the current coordinates of the top left corner of the document and add a percentage relative to the user screen to it and animate the scroll so that the content don't jump and the user looses focus from where he was. The k.which and the $(“span”).text are just so I know what's happening and will be turned into comments when the code is complete. So here is what happens, on Chrome and Firefox the output of the $(“span”).text is correct, starting at 0,0 and always showing how much of the content was scrolled in coordinates, but on IE it starts on -2,-2 and never gets out of it, even if I manually scroll the window until the end of it and try using the right arrow key it will still return the initial value of -2,-2 and scroll back to the beggining. I tried substituting the offset for document.body.scrollLetf and scrollTop but the result is the same, only this time the coordinates are 0,0. Am I doing something wrong? Or is this some IE bug? Is there a way around it or some other function I can use and achieve the same results?

    • http://twitter.com/vandalk Daniel Queiroz Porto

      okay I just solved my problem changing the posk var to “var poskt=$(document).scrollTop();” and adding an new var for scrollLeft, this way the code behave the same on Chrome, FF and Internet Explorer

  • http://twitter.com/vandalk Daniel Queiroz Porto

    I just realized I said something wrong in my last post. actually the k.which variable is not only for me to see what's happening, it's part of the actual code and won't be turned into a comment.

  • Andylwl

    Note: jQuery $(anchor).offset().top seems to change the offset position calculation after a scrolling takes place. For example if you don't scroll the container, the position is 300 from the top. But if you start to scroll abit lower down, the position changes!

    To fix this issue, I use document.getElementById(anchor).offsetTop

    • Dave

      might also try: $(anchor).offset().top – $(window).scrollTop()

  • http://twitter.com/vandalk Daniel Queiroz Porto

    okay I just solved my problem changing the posk var to “var poskt=$(document).scrollTop();” and adding an new var for scrollLeft, this way the code behave the same on Chrome, FF and Internet Explorer

  • http://twitter.com/vandalk Daniel Queiroz Porto

    okay I just solved my problem changing the posk var to “var poskt=$(document).scrollTop();” and adding an new var for scrollLeft, this way the code behave the same on Chrome, FF and Internet Explorer

  • http://twitter.com/vandalk Daniel Queiroz Porto

    okay I just solved my problem changing the posk var to “var poskt=$(document).scrollTop();” and adding an new var for scrollLeft, this way the code behave the same on Chrome, FF and Internet Explorer

  • Guest

    If I apply offset() twice the second time the element is offset relative to its old position and not relative to the document. Is that normal?

  • Csicky

    After IE annoying me with not handling top properly, this saved me from pulling my hair off!
    Thank You again jQuery!