3

I am using following code to make a menu sticky when the window is scrolled down. It works fine if the window height is enough to scroll down the full header area, but it it creates problem is the height is just close enough to scroll, in that case it starts flashing and does not let scroll.

Here is the demo of the problem, refresh couple of times and try to scroll down. I have set the body height to 622px to reproduce the problem:

http://jsbin.com/ipEROYO/1

Here's the code I'm trying:

$(document).ready(function() {
    var stickyNavTop = $('.nav').offset().top;

    var stickyNav = function(){
        var scrollTop = $(window).scrollTop(); 
        if (scrollTop > stickyNavTop) { 
            $('.nav').addClass('sticky');
        } else {
            $('.nav').removeClass('sticky'); 
        }
    };

    stickyNav();

    $(window).scroll(function() {
        stickyNav();
    });
});

CSS:

.sticky {
    position: fixed;
    width: 100%;
    left: 0;
    top: 0;
    z-index: 100;
    border-top: 0;
}
user2738640
  • 1,207
  • 8
  • 23
  • 34

4 Answers4

4

It's because when you are setting the navigation div to position:fixed you are shortening the length of the document (by the height of that div), which then causes the scroll bar to go away, which causes the scrollTop() value to be 0 which causes the .nav div to be position:static and it is an endless cycle if you keep scrolling down.

Here's my quick solution:

$(document).ready(function() {
    var height = $('.nav').outerHeight();
    $(window).scroll(function() {
            if($(this).scrollTop() > height)
            {
                $('.nav').css('position','fixed');
                $('body').css('padding-bottom',height+'px');
            }
            else if($(this).scrollTop() <= height)
            {
                $('.nav').css('position','static');
                $('body').css('padding-bottom','0');
            }
    });
    $(window).scroll();
});
Alex W
  • 37,233
  • 13
  • 109
  • 109
1

Just modified the JSbin. Check it out. You were really close, just doing more than you needed to like setting the sticky class on load of the page rather than when the function first runs. Let me know if this helps.

Keith V
  • 680
  • 4
  • 13
0

try that

     $(window).scroll(function () {

            var scroll_top = $(this).scrollTop();
               if (scroll_top > 66) {//height of header
                 $('.nav').addClass('sticky');
              } else {
              $('.nav').removeClass('sticky');
              }
       });
0

Strongly recommend a CSS only solution for this layout. No one seems to know what to call this method, so I've been referring to it as the absolute stretch technique, but in my experience it works beautifully across mobile devices and PC's including all major browsers except IE6 and below. There is some discussion of it here.

body, .header, .nav, .mainContent{
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
}

body, .mainContent {
    bottom: 0;
}

.header{
    height: 120px;
}

.nav{
    height: 70px;
    top: 120px;
}

.mainContent{
    top: 190px;
    overflow: auto;
}

You'll find you can get very robust, concise, well organized layouts in this manner, and fixed headers, footers and sidebars follow very easily.

Community
  • 1
  • 1
cage rattler
  • 1,587
  • 10
  • 16
  • I use this often for creating 100% height block elements, but how does it translate for sites where either a) content is much taller than viewport height or b) content is too short to push the height of `html` and `body` to the full viewport height (and you need to be able to account for either of those potentials in the layout)? In the former case do you need to use a pane or similar (`overflow:scroll`) or will it work out of the box? In the latter, what's your preferred cross browser solution? – Ennui Oct 15 '13 at 17:15
  • Just curious of your opinion on all that since I find I often run into problems dealing with the "need content to be full height of viewport, but not necessarily cut off at viewport" problem in pure CSS and compatible with IE8+. – Ennui Oct 15 '13 at 17:16