Sticky Vertical Navigation Menu

Last spring I started the thread " Background image taller than the viewport" in which my problem was solved perfectly. I now need to adapt the same idea to a div container, not a background image and I can’t seem to get it to work.

I have a vertical navigation menu in a left sidebar div container with id “primary-navigation” in a WordPress site I am building. The div stretches from the very top of the viewport down to the bottom of the navigation menu. I want the menu to be sticky as the site scrolls, but the problem is that when the site owner decides to add more pages to his navigation menu, it will become longer than the viewport height and the bottom links will not be accessible.

So like the previous thread, I would like the menu to scroll with the rest of the website until its bottom reaches the bottom of the viewport. Then I would like it to stick. And the reverse would happen as the user scrolls up.

Here is what I have so far, but something is wrong with it. Could somebody please take a look and see what isn’t working? Thanks.

jQuery(document).ready(function() {
    $( window ).scroll( function(){
        var ypos = $( window ).scrollTop(), //pixels the site is scrolled down
        visible = $( window ).height(), //visible pixels
        nav_height = $( '#primary-navigation' ).height(), //replace with height of your image
        max_scroll = nav_height - visible; //number of pixels of the image not visible at bottom

        if ( max_scroll < ypos) {
            $('#primary-navigation').css('position', "absolute");
            $('#primary-navigation').css('top', "0 -" + (nav_height - visible)+'px');
            } else {
            $('#primary-navigation').css('position', "fixed");
            $('#primary-navigation').css('bottom', '0');

Here is a jsFiddle of the situation.

Please help me out here. Thanks. :blush:

Here are ten sticky menus that may be helpful.

Thanks for that list, but they seem to be short menus that are sticky, not long ones. I already know how to make a menu sticky.

My problem is when the menu becomes longer than the viewport height - I need to use javaScript to allow the menu to scroll until the bottom links are visible, and then become sticky. And to have the reverse happen when the user scrolls back up to the top of the website.

Try this:

I have added 99 links to the popup menu which now scrolls but is not responsive. The Hamburger menu must be clicked. Maybe some kind soul could add the magic responsive script?

Hamburger King Size

Hmm - still not what I am looking for. I originally had the side navigation fixed while the website scrolled, but that is a problem if the site owner decides to add more pages and make the navigation too long to fit into the viewport. I would like it to scroll with the website only until its bottom reaches the bottom of the viewport, and then become fixed while the website continues to scroll.

Here is a demo I am working on - but the sticky feature isn’t working properly. (291.0 KB)

I have uploaded your demo to my site:

Online Demo

I am not sure if the solution requires knowledge of CSS or JavaScript, perhaps someone can take a look?

It’s the JavaScript that I can’t get to work. I based it off a project where I had the background image do basically the same thing because it was taller than the viewport. I posted what I had so far, but need help fixing it.

It seems to me like the ul itself should be in a div?
that could be positioned relatively then the list & link be allowed to scroll?

this api has an example a bit like it.

Thank you for responding.

The whole sidebar (including the logo that links back to the home page) needs to scroll until its bottom reaches the bottom of the viewport, then remain fixed. Then I need to reverse the process when the website is scrolled back up to the top.

That’s why I put the whole thing in a div that was positioned relative to begin with.

Or maybe would it be better to always have the logo stay fixed in the upper left hand corner, and only have the menu list scroll?

@WebMachine: Is this the sort of thing you’re after?

Yes, exactly! I’m going to try to duplicate that on the website right after lunch. Thank you. What did you change? Was it the ‘static’ instead of ‘absolute’ in the css that made the difference?

I removed the position: fixed; rule from the primary navigation CSS, and changed the JS slightly:

if ( ypos > max_scroll) {
     $('#primary-navigation').css('position', "fixed");
     $('#primary-navigation').css('bottom', '0'); // This can also be moved to the CSS file, it doesn't need to be set via JS
} else {
    $('#primary-navigation').css('position', "static");

Basically ones the page has scrolled down to a point greater than the bottom of the menu, the menu’s position property is changed to fixed which, combined with the bottom: 0; rule, ensures that the menu stays fixed to the bottom of the viewport. Once that condition is no longer true (when you scroll back up) it toggles the position property back to static (the default).

Fret, what about just adding a class? Keep the CSS, in the CSS

if ( ypos > max_scroll) {
} else {
#primary-navigation {
#primary-navigation.sticky {

The jQuery probably isn’t right, but the concept is there.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.