Disappearing Nav

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";
}

Leave a Reply

Your email address will not be published. Required fields are marked *