Home » Html » Stick div to top of parent element

Stick div to top of parent element

Posted by: admin November 30, 2017 Leave a comment

Questions:

I want to stick the div to the top of its parent element.

It generally works, except in this example: http://jsfiddle.net/HV9HM/2859/

function sticky_relocate() {
    var window_top = $('#container').scrollTop();
    var div_top = $('#sticky-anchor').offset().top;
    if (window_top > div_top) {
        $('#sticky').addClass('stick');
        $('.stick').css('width', $('#sticky').next().css('width'));
    } else {
        $('#sticky').removeClass('stick');
    }
}

$(function () {
    $('#container').scroll(sticky_relocate);
    sticky_relocate();
});
.child {
    height: 200px;
    background: gray;
}

#sticky {
    padding: 0.5ex;
    width: 600px;
    background-color: #333;
    color: #fff;
    font-size: 2em;
    border-radius: 0.5ex;
}
#sticky.stick {
    position: fixed;
    z-index: 10000;
    border-radius: 0 0 0.5em 0.5em;
}
body {
    margin: 1em;
}
p {
    margin: 1em auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br>
<br>
<br>

<div id="container" style="overflow-y: auto; height: 800px;">
  <div id="sticky-anchor"></div>
  <div id="sticky">This will stay at top of page</div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>
Answers:

The reason this is happening is that as soon as you give position: fixed to your #sticky element, it takes it out of the document flow. This means that all of your div.child elements shift up, which makes the height of your container element get smaller. Because the container element height gets smaller, the container element no longer needs to scroll, which means its scrollbar disappears and its scroll position is reset to 0. When its scroll position is reset to 0, the script again removes the stick class from your #sticky element and we are back where we started, but with the container element scrolled all the way to the top.

In summary:

  1. #sticky element gets .stick class.

  2. #sticky element is removed from document flow, child elements shift up, container element height decreases and scrollbar disappears. Container’s scrollTop is reset to 0.

  3. Script fires again, removing the .stick class from #sticky, and the container’s scrollTop remains at 0 (thus the container div is scrolled back up to the top).

Below is a solution that uses position: absolute for the #sticky element, and when the #sticky element gets the stick class, it gives the #sticky-anchor element a height equal to the height of the #sticky element to prevent the child divs from shifting upwards.


Working Live Demo:

function sticky_relocate() {
    var window_top = $('#container').scrollTop();
    var div_top = $('#sticky-anchor').offset().top;
    $('.stick').css('width', $('#sticky').next().css('width'));
    if (window_top > div_top) {
        $('#sticky-anchor').height($("#sticky").outerHeight());
        $('#sticky').addClass('stick');
        $("#sticky").css("top", (window_top) + "px");
    } else {
        $('#sticky').removeClass('stick');
        $('#sticky-anchor').height(0);
    }
}

$(function () {
    $('#container').scroll(sticky_relocate);
    sticky_relocate();
});
.child {
    height: 200px;
    background: gray;
}

#sticky {
    padding: 0.5ex;
    background-color: #333;
    color: #fff;
    font-size: 2em;
    border-radius: 0.5ex;
}
#sticky.stick {
    position: absolute;
    top: 0;
    z-index: 10000;
    border-radius: 0 0 0.5em 0.5em;
}
body {
    margin: 1em;
}
p {
    margin: 1em auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br>
<br>
<br>

<div id="container" style="overflow-y: auto; height: 800px; position: relative;">
  <div id="sticky-anchor"></div>
  <div id="sticky">This will stay at top of page</div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>

JSFiddle Version: http://jsfiddle.net/HV9HM/2883/


As a side note, the reason it was working fine in your second example is that the additional child element made it so that even when your #sticky element was removed from document flow and the container element’s height was reduced, the height of the container element was still large enough to keep the scrollbar from jumping/disappearing and changing/resetting your scrollTop.

Questions:
Answers:

Although the best answer to this particular question is clearly @MaximillianLaumeister’s, here is a general solution for fixing an element to another element.

Tether

Tether is a JavaScript library for efficiently making an absolutely
positioned element stay next to another element on the page.

Tether includes the ability to constrain the element within the
viewport, its scroll parent, any other element on the page, or a fixed
bounding box.

http://github.hubspot.com/tether/

Questions:
Answers:

along with position:fixed;you also need to provide the sticky nav bar a higher z-index value than the other elements of the same page as z-index:blah;

Questions:
Answers:
<table>
<tr class="relative" id="header">
    <td>header
    </td>
</tr>

<tr id="content">
    <td>table content
    </td>
</tr>    

$(window).scroll(function() {

      if ($(window).scrollTop() > 140) {
        $("#header").addClass("fixed");
      } else {
        $("#header").removeClass("fixed");
      }
});

take refrence from below example
https://jsfiddle.net/nckv9mso/

Questions:
Answers:

The problem arises when the containers height is x and the content of the container is less than x+36px. In this example the container is 800px and the content is less than 836px. My idea for the solution was to check the height of the content and compare it to the height of the container and if the difference was less than 36px, just not to add the stick class.

Questions:
Answers:

its very simple, Just add the following styling for the specific sticky div.

sticky{position: fixed;}