Make scrolling sidebar stop at footer

34,304

Solution 1

You can check if you've scrolled down to the footer, then remove the stick class:

function sticky_relocate() {
    var window_top = $(window).scrollTop();
    var footer_top = $("#footer").offset().top;
    var div_top = $('#sticky-anchor').offset().top;
    var div_height = $("#sticky").height();

    if (window_top + div_height > footer_top)
        $('#sticky').removeClass('stick');    
    else if (window_top > div_top) {
        $('#sticky').addClass('stick');
    } else {
        $('#sticky').removeClass('stick');
    }
}

(you could combine the if to remove the duplicate .removeClass, here for demonstration)

However, with your css you get a nasty 'jump' around when you start scrolling - in your fiddle, the right content appears below #sticky then when you stick #sticky, the right content jumps to fill the gap. Using the code above, you'll get some race-conditions as the offset() moves when it fills/unfills the gap.

To fix this gap, just add a float:left to your #sticky css.

Updated fiddle: http://jsfiddle.net/0mLzseby/472/


I suspect you would like to go one step further and, when you get to the bottom, the div then starts to scroll with the page. You can do this by adjusting the 'position:fixed' top of .stick. Don't forget to reset it when not below the footer:

function sticky_relocate() {
    var window_top = $(window).scrollTop();
    var footer_top = $("#footer").offset().top;
    var div_top = $('#sticky-anchor').offset().top;
    var div_height = $("#sticky").height();

    var padding = 20;  // tweak here or get from margins etc

    if (window_top + div_height > footer_top - padding)
        $('#sticky').css({top: (window_top + div_height - footer_top + padding) * -1})
    else if (window_top > div_top) {
        $('#sticky').addClass('stick');
        $('#sticky').css({top: 0})
    } else {
        $('#sticky').removeClass('stick');
    }
}

The padding just makes it start scrolling in a more natural place - you can probably get this from other css attributes such as margin and padding of the other components.

Updated fiddle: http://jsfiddle.net/0mLzseby/473/

Solution 2

This can now be achieved without javascript using position: sticky.

Updated fiddle: http://jsfiddle.net/p1gku0mx/3/

The key is to wrap the sticky element in another div. Since the sticky element cannot move outside of its wrapper div it get scrolled up when the footer comes into view.

Solution 3

You forgot to add class, if we are in the footer, and refrech the page, then, the sidebar won't show :

function sticky_relocate() {
    var window_top = $(window).scrollTop();
    var footer_top = $("#footer").offset().top;
    var div_top = $('#sticky-anchor').offset().top;
    var div_height = $("#sticky").height();

    var padding = 20;  // tweak here or get from margins etc

    if (window_top + div_height > footer_top - padding) {
        $('#sticky').addClass('stick'); //////// here is to get fixed when we refrech page when we are in the footer
        $('#sticky').css({top: (window_top + div_height - footer_top + padding) * -1})
}     else if (window_top > div_top) {
        $('#sticky').addClass('stick');
        $('#sticky').css({top: 0})
    } else {
        $('#sticky').removeClass('stick');
    }
}

Solution 4

You don't need to use javascript for this. You can do this using CSS only:

position: sticky;

body{
  padding: 0 20px;
}
#content {
  height: 1200px;
}
header {
  width: 100%;
  height: 150px;
  background: #aaa;
}
main {
  float: left;
  width: 65%;
  height: 100%;
  background: #444;
}
aside {
  float: right;
  width: 30%;
  height: 500px;
  position: sticky;
  top: 100px;
  background: #777;
}
footer {
  width: 100%;
  height: 300px;
  background: #555;
}
<body>
  <header>Header</header>
  <div id="content">
    <main>Content</main>
    <aside>Sidebar</aside>
  </div>
  <footer>Footer</footer>
</body>

Share:
34,304
BN83
Author by

BN83

Updated on July 25, 2022

Comments

  • BN83
    BN83 almost 2 years

    I'm currently using the following:

    http://jsfiddle.net/0mLzseby/469/

    To make my sidebar follow down the page. I have quite a large footer though and I'd like the div to stop when it gets to the footer rather than to keep scrolling.

    The code I currently have is:

    function sticky_relocate() {
        var window_top = $(window).scrollTop();
        var div_top = $('#sticky-anchor').offset().top;
        if (window_top > div_top) {
            $('#sticky').addClass('stick');
        } else {
            $('#sticky').removeClass('stick');
        }
    }
    
    $(function () {
        $(window).scroll(sticky_relocate);
        sticky_relocate();
    });
    
  • BN83
    BN83 about 8 years
    Perfect thank you. Had to make some tweaks when putting it in to the final page, but this has done the trick brilliantly. Marked as answered, thanks!
  • Krzysztof Antosik
    Krzysztof Antosik about 3 years
    I'm glad that I could help. If you need a two-way sticky sidebar check out my github: github.com/Antosik-dev/Two-direction-Sticky-Sidebar