Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery offset().top returns wrong value - error with margin

if you try to get a top offset from a list element within a parent, and that parent is not positioned at the top, you will get a wrong value.

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

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

What is the solution for this problem?

like image 476
user3631654 Avatar asked Mar 26 '15 11:03

user3631654


2 Answers

Your question:

What is the solution for this problem?

I suggest you to position the .container to relative:

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

and within your script use .position().top, it will make your life easier:

$('.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 is calculated from the top to the parent if 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>
like image 175
Jai Avatar answered Oct 31 '22 19:10

Jai


You can also encounter this problem if some of your content is images. If you're calling .offset() inside document.ready(), the images may not have loaded yet. Try moving your .offset() call to window.load().

like image 9
Nate Avatar answered Oct 31 '22 20:10

Nate