Coder Perfect

How can I make a div that has been scrolled to the top of the screen stay there?

Problem

I’d like to make a div that sits beneath a block of content but becomes fixed in place and scrolls with the page once the page has been scrolled sufficiently to reach its top border.

Asked by evanr

Solution #1

You could just use css and set your element’s position to fixed:

.fixedElement {
    background-color: #c0c0c0;
    position:fixed;
    top:0;
    width:100%;
    z-index:100;
}

Edit: You should have the element with absolute position, then change it to fixed once the scroll offset has reached it, and set the top position to zero.

The scrollTop function can be used to determine the document’s top scroll offset:

$(window).scroll(function(e){ 
  var $el = $('.fixedElement'); 
  var isPositionFixed = ($el.css('position') == 'fixed');
  if ($(this).scrollTop() > 200 && !isPositionFixed){ 
    $el.css({'position': 'fixed', 'top': '0px'}); 
  }
  if ($(this).scrollTop() < 200 && isPositionFixed){
    $el.css({'position': 'static', 'top': '0px'}); 
  } 
});

Because the element is put as fixed, when the scroll offset reaches 200, it will stick to the top of the browser window.

Answered by Christian C. Salvadó

Solution #2

This example may be found on the issue page of Google Code and (most recently) on the edit page of Stack Overflow.

CMS’s answer doesn’t revert the positioning when you scroll back up. Here’s the code, which I shamelessly grabbed from Stack Overflow:

function moveScroller() {
    var $anchor = $("#scroller-anchor");
    var $scroller = $('#scroller');

    var move = function() {
        var st = $(window).scrollTop();
        var ot = $anchor.offset().top;
        if(st > ot) {
            $scroller.css({
                position: "fixed",
                top: "0px"
            });
        } else {
            $scroller.css({
                position: "relative",
                top: ""
            });
        }
    };
    $(window).scroll(move);
    move();
}
<div id="sidebar" style="width:270px;"> 
  <div id="scroller-anchor"></div> 
  <div id="scroller" style="margin-top:10px; width:270px"> 
    Scroller Scroller Scroller
  </div>
</div>

<script type="text/javascript"> 
  $(function() {
    moveScroller();
  });
</script> 

There’s also a little live demonstration.

position: sticky, which is supported in Chrome, Firefox, and Safari, is a new script-free option. See the HTML5Rocks article and demo, as well as the Mozilla documentation.

Answered by Josh Lee

Solution #3

Most browsers in regular use support the position: sticky attribute in CSS as of January 2017, when Chrome 56 was released.

#thing_to_stick {
  position: sticky;
  top: 0px;
}

In both Firefox and Chrome, this works for me.

In Safari you still need to use position: -webkit-sticky.

For Internet Explorer and Edge, polyfills are available; https://github.com/wilddeer/stickyfill appears to be a decent one.

Answered by Colin ‘t Hart

Solution #4

I experienced the same issue as you and had to create a jQuery plugin to solve it. It truly solves all of the issues described here, as well as adding a handful other optional features.

stickyPanelSettings = {
    // Use this to set the top margin of the detached panel.
    topPadding: 0,

    // This class is applied when the panel detaches.
    afterDetachCSSClass: "",

    // When set to true the space where the panel was is kept open.
    savePanelSpace: false,

    // Event fires when panel is detached
    // function(detachedPanel, panelSpacer){....}
    onDetached: null,

    // Event fires when panel is reattached
    // function(detachedPanel){....}
    onReAttached: null,

    // Set this using any valid jquery selector to 
    // set the parent of the sticky panel.
    // If set to null then the window object will be used.
    parentSelector: null
};
https://github.com/donnyv/sticky-panel

demo: http://htmlpreview.github.io/?https://github.com/donnyv/sticky-panel/blob/master/jquery.stickyPanel/Main.htm

Answered by Donny V.

Solution #5

Here’s how to do it without jquery (UPDATE: see other answers where you can now do this with CSS only)

Answered by Jim W says reinstate Monica

Post is based on https://stackoverflow.com/questions/1216114/how-can-i-make-a-div-stick-to-the-top-of-the-screen-once-its-been-scrolled-to