javascripthtmlcssnavbar

Resize Navigation Bar with Sticky


I found a very simple way to make a sticky navigation bar here: https://www.w3schools.com/howto/howto_js_navbar_sticky.asp

My code pretty much mirrors the example except I have a height set on mine:

window.onscroll = function() {
  myFunction()
};
var navbar = document.getElementById("navbar");
var sticky = navbar.offsetTop;

function myFunction() {
  if (window.pageYOffset >= sticky) {
    navbar.classList.add("sticky")
  } else {
    navbar.classList.remove("sticky");
  }
}
#navbar {
  background-color: #333;
  height: 145px;
  overflow: hidden;
}

#navbar a {
  float: left;
  display: block;
  color: #f2f2f2;
  text-align: center;
  padding: 14px;
  text-decoration: none;
}

.content {
  padding: 16px;
}

.sticky {
  height: 85px;
  position: fixed;
  top: 0;
  width: 100%;
  z-index: 1;
}

.sticky+.content {
  padding-top: 145px;
}
<div id="navbar">
  <a href="#home">Home</a>
  <a href="#news">News</a>
  <a href="#contact">Contact</a>
</div>

What I wanted to do is have a shorter navbar only when I scroll down. So, I added a height to my .sticky class and then I was hoping when I scrolled down then my default height would get overridden by my sticky class. When I look at the code, the sticky class gets added after my navbar ID, which is probably why that doesn't work.

I don't know what I need to change to make this happen. Does anyone have any suggestions? I haven't been able to find an example of this functionality.


Solution

  • First you do have a specificity problem between id and class that is why don't see a height change. I also used position sticky. If you want to avoid the shaky behaviour of your navbar when scrolling near the change point you need to add the var sticky inside the eventlistener like this it is updated at each scroll. I also used nav tag and div.forheight to allow scroll

    var navbar = document.querySelector(".navbar");
    window.addEventListener('scroll',myFunction)
    
    function myFunction() {
        var sticky = navbar.offsetHeight;
        if(window.scrollY>sticky){
            navbar.classList.add('sticky')
        }else{
            navbar.classList.remove('sticky')
        }
    }  
    .navbar {
        background-color: #333;
        top:0;
        position:sticky;
        height: 145px;
      }
      
      .navbar ul {
        display:flex;
        width:100%;
        flex-direction:row;
        justify-content:space-between;
        list-style-type:none;
      }
      
      .sticky {
        height: 85px;
      }
      
      .forheight{
        display: block;
        height:150vh;
      }
    <nav class="navbar">
        <ul>
          <li><a href="#home">Home</a><li>
          <li><a href="#news">News</a><li>
          <li><a href="#contact">Contact</a><li>
        </ul>
    </nav>
      <div class='forheight'></div>

    for your nav bar