Auto-Hiding Navigation

Auto-Hiding Navigation

A simple navigation that auto-hides when the user scrolls down, and becomes visible when the user scrolls up.

Nucleo icons

Sponsored by Nucleo, a free application to collect, customize and export all your icons as icon font and SVG symbols. Made by the CodyHouse folks!

Do you want to include this resource in a product offered for sale? Learn more about our Extended License

Auto-hiding navigations have been around for quite some time now, in particular on mobile devices. The idea behind this UX pattern is simple yet efficient: we want the navigation to be easy to reach all the time, so we stick it on top. However, we auto-hide it when the user scrolls down, to create more room for the content. If the user scrolls up, we interpret his behaviour as a will to access the navigation, so we bring it back.

Since we’ve been using this approach in several clients’ projects, we thought it would be handy to have a ready-to-use snippet here on CodyHouse.

Images: Unsplash

Creating the structure

The HTML structure is composed of a header.cd-auto-hide-header element used to wrap the primary navigation (nav.cd-primary-nav) and a main.cd-main-content for the page main content.

<header class="cd-auto-hide-header">
   <div class="logo"><a href="#0"><img src="img/cd-logo.svg" alt="Logo"></a></div>

   <nav class="cd-primary-nav">
      <a href="#cd-navigation" class="nav-trigger">
         <span>
            <em aria-hidden="true"></em>
            Menu
         </span>
      </a> <!-- .nav-trigger -->

      <ul id="cd-navigation">
         <li><a href="#0">The team</a></li>
         <li><a href="#0">Our Services</a></li>
         <li><a href="#0">Our Projects</a></li>
         <li><a href="#0">Contact Us</a></li>
      </ul>
   </nav> <!-- .cd-primary-nav -->
</header> <!-- .cd-auto-hide-header -->

<main class="cd-main-content">
   <!-- content here -->
</main> <!-- .cd-main-content -->

If the page has a sub-navigation, an additional nav.cd-secondary-nav is inserted inside the header element:

<header class="cd-auto-hide-header">
   <div class="logo"><a href="#0"><img src="img/cd-logo.svg" alt="Logo"></a></div>

   <nav class="cd-primary-nav">
      <a href="#cd-navigation" class="nav-trigger">
         <span>
            <em aria-hidden="true"></em>
            Menu
         </span>
      </a> <!-- .nav-trigger -->

      <ul id="cd-navigation">
         <!-- links here -->
      </ul>
   </nav> <!-- .cd-primary-nav -->

   <nav class="cd-secondary-nav">
      <ul>
         <li><a href="#0">Intro</a></li>
         <!-- additional links here -->
      </ul>
   </nav> <!-- .cd-secondary-nav -->
</header> <!-- .cd-auto-hide-header -->

<main class="cd-main-content sub-nav">
   <!-- content here -->
</main> <!-- .cd-main-content -->

Finally, if the secondary navigation is below a hero block, a .cd-hero element is inserted right below the <header>, followed by the .cd-secondary-nav element:

<header class="cd-auto-hide-header">
   <div class="logo"><a href="#0"><img src="img/cd-logo.svg" alt="Logo"></a></div>

   <nav class="cd-primary-nav">
      <a href="#cd-navigation" class="nav-trigger">
         <span>
            <em aria-hidden="true"></em>
            Menu
         </span>
      </a> <!-- .nav-trigger -->

      <ul id="cd-navigation">
         <!-- links here -->
      </ul>
   </nav> <!-- .cd-primary-nav -->
</header> <!-- .cd-auto-hide-header -->

<section class="cd-hero">
   <!-- content here -->
</section> <!-- .cd-hero -->

<nav class="cd-secondary-nav">
   <ul>
      <!-- links here -->
   </ul>
</nav> <!-- .cd-secondary-nav -->

<main class="cd-main-content sub-nav-hero">
   <!-- content here -->
</main> <!-- .cd-main-content -->

Adding style

We used the .cd-auto-hide-header class to define the main style of the auto-hiding header. By default, the header has a fixed position and a top of zero; when the user starts scrolling down, the .is-hidden class is used to hide the header right above the viewport.

.cd-auto-hide-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 60px;
  transition: transform .5s;
}
.cd-auto-hide-header.is-hidden {
  transform: translateY(-100%);
}

In the style.css file (or style.scss if you are using Sass) the code you find right below the comment '1. Auto-Hiding Navigation - Simple' is the one you need to include in your project if you are using the 'Simple' auto-hiding navigation (primary navigation only).

If your header has a sub-navigation (right below the primary navigation), then you need to include also the style you find under the '2. Auto-Hiding Navigation - with Sub Nav' comment. This second block of code is used to define the main style for the secondary navigation (using the .cd-secondary-nav class).

Finally, if your secondary navigation is below a hero section, in addition to the previous two blocks you need to include also the code under the '3. Auto-Hiding Navigation - with Sub Nav + Hero Image' section. This is used to define two classes, .fixed and .slide-up, which are added to the secondary navigation while scrolling (the first one to make it 'sticky' and the second to slide it up when the primary navigation is hidden).

.cd-secondary-nav.fixed {
  position: fixed;
  top: 60px;
}
.cd-secondary-nav.slide-up {
  transform: translateY(-60px);
}

Finally, the \Main content'  and 'Intro Section' blocks are used to define the basic style for the .cd-main-content and .cd-hero elements (mostly padding/margin to account for the fixed header).

Events handling

We use jQuery to listen for the scroll event on the window object.

var scrolling = false;
   $(window).on('scroll', function(){
      if( !scrolling ) {
         scrolling = true;
         (!window.requestAnimationFrame)
            ? setTimeout(autoHideHeader, 250)
            : requestAnimationFrame(autoHideHeader);
      }
});

The autoHideHeader() function takes care of hiding/revealing the navigation according to whether the user is scrolling up or down.

Join our newsletter

Get our monthly recap with the latest CodyHouse news