JQuery offset (). top returns an invalid value - a margin error

if you try to get the top offset from the list item in the parent, and that parent is not located at the top, you will get the wrong value.

http://jsbin.com/yuxacuduna/1/edit?html,css,js,console,output

Try removing the margin-top in the .container element and you will see that it will work.

What is the solution to this problem?

+8
javascript jquery html css jquery-animate
source share
4 answers

Your question:

What is the solution to this problem?

I suggest you set .container to relative :

 .container{ margin-top:100px; background:yellow; height:600px; width:300px; overflow-y:auto; overflow-x:hidden; position:relative; /*<---add this*/ } 

and in your script use .position().top , this will simplify your life:

 $('.container li:nth-child(7)').css("background", "red"); $('.container').animate({ scrollTop: $('.container li:nth-child(7)').position().top }); 

.offset().top :
Description Get the current coordinates of the first element in the set of matched elements relative to the document.

.position().top :
From the docs:

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

.position().top calculated from the top to the parent if the parent is relatively positioned.

 $(function() { $('.container li:nth-child(7)').css("background", "red"); $('.container').animate({ scrollTop: $('.container li:nth-child(7)').position().top }); }); 
 html, body { margin: 0; padding: 0; } .container { margin-top: 100px; background: yellow; height: 600px; width: 300px; overflow-y: auto; overflow-x: hidden; position: relative; } .container ul { margin: 0; padding: 0; list-style: none outside none; } .container li { background: blue; display: block; height: 150px; width: 100%; padding: 10px; margin-bottom: 5px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="container"> <ul> <li>asdasd</li> <li>asdasd</li> <li>asdasd</li> <li>asdasd</li> <li>asdasd</li> <li>asdasd</li> <li>asdasd77</li> <li>asdasd</li> <li>asdasd</li> <li>asdasd</li> <li>asdasd</li> </ul> </div> 
+19
source share

You may also encounter this problem if some of your images are images. If you call .offset () inside document.ready (), the images may not load yet. Try moving the .offset () call to window.load ().

+1
source share

I think it works correctly. According to the documentation of offset() jQuery :

The .offset () method allows us to get the current position of an element relative to a document

So the problem is that you are trying to scroll ul , but with the scrollTop value of the element inside the document , not inside the list. To fix this, simply correct the value given the scrollTop of the parent ( ul ):

 $(function(){ $('.container li:nth-child(7)').css("background", "red"); $('.container').animate({ scrollTop: $('.container li:nth-child(7)').offset().top - $(".container").offset().top }); }); 

You can see how he works on this edit of your JSBin: http://jsbin.com/fanixodiwi/1/edit?html,css,js,console,output

0
source share

I had the same problem. All solutions on the Internet do not work for me.

If you use margin to separate certain elements without borders, use a spacer instead. jQuery offset () will count for paddings, but excludes fields. The position numbers in offset () will be corrected again.

0
source share

All Articles