Go to homepage

Projects /

Auto-Hiding Navigation

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

Auto-Hiding Navigation
Check our new component library →

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

👋 A new version of this component is available. Download now →.

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.

Project duplicated

Project created

Globals imported

There was an error while trying to export your project. Please try again or contact us.