Nate Northway

Disappearing Nav

blog | October 13, 2016

Disappearing navbars are found all over the web. This feature may seem like an advanced technique, but it's actually really easy to implement. With just a little bit of JavaScript, you can have a disappearing navbar.

The logic

When the user scrolls down, the navbar fades out. When the user scrolls up, the navbar fades in. Easy, right? We need to take into account the page position when the user starts to scroll. This helps determine if the direction of the scroll is up or down. So, when the user starts to scroll, we need to save the pageYOffset, or, the distance from the top the page is scrolled. Then, we need to figure out if the user has scrolled up or down. To figure that out, we check if the current position is greater than the last saved position. If the current position is greater, that means that the user has scrolled down. If the position is less, the user has scrolled up. Let's code this out:

var lastPosition = 0;
window.onscroll = function() {
  var position = window.pageYOffset;

  if (position > lastPosition) {
    //the user has scrolled down
  } else {
    //the user has scrolled up
  }
}

That's the bulk of our code. Now, we just need to hide and show the header. There are a few different ways to do this. I'm using CSS classes, hidden and active, with different opacities. Here is that code:

.hidden {
  transition: opacity .4s ease;
  opacity: 0;
  pointer-events: none;
}
.active {
  transition: opacity .4s ease;
  opacity: 1;
}

This adds a little bit of a transition and makes whatever is in the header non-interactive while it's hidden. Putting it all together is simple: when the user scrolls down, the header's class should be hidden, and when the user scrolls up, the header's class should be active. Here's the code:

var lastPosition = 0;
window.onscroll = function() {
  var position = window.pageYOffset;

  if (position > lastPosition) {
    //the user has scrolled down
    document.getElementById("header").className = "hidden";
  } else {
    //the user has scrolled up
    document.getElementById("header").className = "active";
  }
}

Of course, this snippet only works with navbars that are fixed to some side of the screen. I think this effect looks great on mobile and really frees up a lot of screen real estate. Here's your demo:

See the Pen Disappearing Navbar by Nate Northway (@the_Northway) on CodePen.

Add jQuery

You can get a little more into this with jQuery. The first thing I did was replace the <header>'s hidden and active class names with the jQuery fadeIn() and fadeOut() effects. This handily also takes care of disabling interaction in the header. The jQuery code is not that different. We should also adjust the threshold so that a small amount of scrolling up does not trigger the menu - this is important when thinking of more sensitive input devices like a touch screen or a track pad. That's just a little bit of logic. If the difference between the last position and current position is greater than 20, we know that the user has scrolled up a lot and quickly, so we should show the navigation. Here is that demo, with the relevant jQuery below:

$(document).ready(function() {
  var lastPosition = 0;
  $(window).on('scroll', function() {
    var position = $(window).scrollTop();

    if (position > lastPosition) {
      $("#header").fadeOut();
    } else if (lastPosition - position > 20) {
      $("#header").fadeIn();
    }

    lastPosition = position;
  })
})

Really Get Into It

The next thing you can do to bring this effect to being fully fleshed out is changing the opacity based on the amount that the user has scrolled. To do this, we have to take into account the <header>'s opacity before scrolling, decrement it, and set the new opacity to that decremented amount. If the new opacity is 0 (or less), we should also disable pointer-events. Here is that code:

...
  if (position > lastPosition) {
    opacity = getOpacity($("#header").css("opacity"));
    $("#header").css({"opacity": opacity});
    if (opacity <= 0) {
      $("#header").css({
        "opacity": 0,
        "pointer-events": "none"
        });
    }
  }
...

function getOpacity(x) {
  var rate = .25;
  return x - rate;
}

This decrements the opacity by .25 every time the user scrolls. Remember to set pointer-events to auto on scroll up, otherwise, your users will not be able to interact with your navbar after scrolling down or refreshing. Here is that demo:

See the Pen Disappearing Navbar (with jQuery) by Nate Northway (@the_Northway) on CodePen.

I had fun building this set of demos. Hopefully it can come in handy on your site!

Edit:

I posted this on Reddit and got a good reply from /u/alejalapeno:

All iterations of this need a debounce/threshold put on them because a 1px scroll-up on a trackpad should not re-summon the menu. It needs a threshold like 10-20 pixels scrolled-up at least.

I added that in as a condition to the if statement in the JS. It checks if the difference between lastPosition and position is greater than 20px before showing the navbar. I've already updated all the sample code above and on in the CodePen demos, but here's a closer look at it:

if (position > lastPosition) {
  document.getElementById("header").className = "hidden";
} else if (lastPosition - position > 20) {
  document.getElementById("header").className = "active";
}

Reply

Your email address will not be published.All Fields Are Required

< Previous Post: Browser DefaultsNext Post: Content Security Policy >