Search code examples
javascriptjqueryheaderfixed

Fixed Header when the Div above is scrolled past


I have this setup so that when the page is scrolled 400px the #headermenu becomes fixed. However the div above this one will have a variable height depending on the screen size.

I need the JS to make the #headermenu become fixed when the bottom of the div above it(#mixedheightheader) has reached the top of the window.

JSFIDDLE

Thanks in advance for you help

<div id="mixedheightheader"></div>

$(function() {    
  $('#headermenu');
});

$(window).scroll(function() {    
  if ($(document).scrollTop() < 400)     {        
    if ($('#headermenu'))         {            
      $('#headermenu');            
      $('#headermenu').stop().css({
        top: '0',
        position: 'relative'
      });        
    }    
  }    
  else     {        
    if ($('#headermenu'))         {            
      $('#headermenu');            
      $('#headermenu').stop().css({
        top: '0',
        position: 'fixed'
      });        
    }      
  }
});
body {
  height: 3000px
}

#headermenu {
  width: 100%;
  background: black;
  min-height: 100px;
}

#mixedheightheader {
  top: 0;
  bottom: 0;
  width: 100%;
  height: 100vh;
  min-height: 200px;
  overflow: hidden;
  background: grey;
  clear: both;
}

#below {
  width: 100%;
  background: darkgrey;
  height: 100px;
  position: relative;
  z-index: -1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mixedheightheader"></div>
<div id="headermenu"></div>
<div id="below"></div>


Solution

  • I have updated you fiddle:

    https://jsfiddle.net/yLon2oj3/11/

    $(function() {    
      var isFixed = false; //This is to not fix if already fixed and reverse
    
        $(window).scroll(function() {
        var mixedHeightHeader = $('#mixedheightheader');
        //This uses the offset top position and the height to calculate the bottom of your variable header
        var mixedHeightHeaderBottom = mixedHeightHeader.offset().top + mixedHeightHeader.height();
        var headerMenu = $('#headermenu');
    
    
        if ($(document).scrollTop() < mixedHeightHeaderBottom && isFixed)       {        
            if (headerMenu) {                  
            headerMenu.css({
                top: '0',
                position: 'relative'
            });  
            isFixed = false;
            //this is to remove the placeholder space of the fixed top nav, when its not fixed to top
            mixedHeightHeader.css('margin-bottom', '0');
          }    
        }    
        else  if ($(document).scrollTop() > mixedHeightHeaderBottom && !isFixed)   {        
          if (headerMenu) {                      
            headerMenu.css({
              top: '0',
              position: 'fixed'
            });
            //This holds the position that was occupied by the fixed top nav when it was a relative element, because its now taken out of the flow.
            mixedHeightHeader.css('margin-bottom', headerMenu.height() + 'px');
          }
          isFixed = true;
        }
        });
    
    });