How to Code a Fixed Auto-Hiding Nav Bar with JavaScript

Top navigation bars have always been popular in web design. Since these elements contain such vital information some designers like to keep them fixed on-screen while scrolling down the page. But unfortunately, this can get in the way of content if the bar is too large. A popular online blogging platform Medium created an interesting method of hiding the bar when scrolling down and re-showing it when scrolling back up.

In this tutorial I want to demonstrate how you can achieve this effect on your own website. I'll be using Headroom.js which is a free open source JavaScript library and jQuery/Zepto plugin. The effect requires a bit of custom CSS along with a small block of JS code. Take a peek at my live demo to see the final result.

Getting Started

First we need a local copy of the Headroom.js script which you can download from the plugin website or from the Github repo. I'm using the minified version but they both contain the same exact code. Now the initial setup requires a fixed header bar that stays on top of the page using basic CSS properties.

I've created a new stylesheet named styles.css along with a primary HTML document. Everything is included into the document header like so:

<meta content="text/html">
<meta content="width=device-width">
<meta content="Jake Rocheleau">
<link rel="shortcut icon" href="">
<link rel="icon" href="">
<link rel="stylesheet" href="css/styles.css">
<header id="header" class="header fixed">
<div class="wrap">
<div class="clearfix" style="width: 100%;">
<div id="logo">SomeLogo</div>
<ul id="navmenu">
<li><a>About Us</a></li>
The actual header element using the ID #header is most important here. This will stay fixed on the layout and naturally scroll down with the user. #header is targeted using JavaScript to add the headroom function, but the .fixed class is where we get all the natural CSS positioning.

CSS Setup

This stage can get a little confusing but I hope to simplify as much as possible. The Headroom plugin requires a large amount of CSS, but unfortunately this isn't clarified on the plugin's homepage. My demo CSS file is split into different code sections and towards the bottom you'll find a whole bunch of animations and keyframes using CSS3 properties.

In order to get your page working you should copy this CSS into your own stylesheet. Various classes pertain to different animations where the header bar will slide up out of view or slide down into view.
/** page structure **/
.wrap {
  display: block;
  margin: 0 auto;
  max-width: 800px;
  padding: 0 10px;

#content {
  padding: 110px 0;

#header {
  display: block;
  width: 100%;
  height: 80px;
  background: #4e5f81;
  -webkit-box-shadow: 1px 2px 4px rgba(0,0,0,0.4);
  -moz-box-shadow: 1px 2px 4px rgba(0,0,0,0.4);
  box-shadow: 1px 2px 4px rgba(0,0,0,0.4);
  position: fixed;
  z-index: 10;
  right: 0;
  left: 0;
  top: 0;

In this first block I've outlined each critical element of my page. .wrap is a responsive wrapper that contains the header and page body content. Also remember the #header ID only adds design properties onto the navbar - .fixed is what creates the auto-scroll positioning.

#navmenu {
  display: block;
  float: right;
#navmenu li {
  display: block;
  float: left;	

#navmenu li a {
  display: block;
  float: left;
  padding: 0 20px;
  font-size: 1.4em;
  line-height: 80px;
  font-weight: bold;
  color: #fff;
  text-decoration: none;

#navmenu li a:hover {
  background: #617398;

/** simple responsive updates **/

@media screen and (max-width: 500px) {
  #navmenu li a { font-size: 1.2em; padding: 0 15px; }
  #logo { font-size: 2.1em; }
  h1 { font-size: 2.7em; }
  p { font-size: 1.6em; }

Afterwards I'm aligning the various navigation items in the unordered list. You may not need these properties if your header already has navigation setup. Also my custom responsive CSS will adjust font sizes based on various screen displays.

Just beyond these responsive codes you'll notice a huge section of CSS delimited by the comment line /** headroom.js animated styles **/. Everything beyond that comment should be copied into your own CSS file, aside from the clearfix classes which are just typical float resets.

I've tried to organize each section by breaking them up with CSS comments. Headroom's CSS is the most extensive yet necessary part of the whole setup. In the future I hope these codes may be added into a separate file in Github because I wasn't able to create the auto-hiding header effect without these animation codes.

Headroom JS Method

Moving back into the HTML file open a new script tag at the very bottom before closing the body section. We need to use a large block of JS to initialize the Headroom plugin class while passing some optional parameters.

var header = document.querySelector("#header");

new Headroom(header, {
  tolerance: {
    down : 2,
    up : 5
  offset : 100,
  classes: {
    initial: "slide",
    pinned: "slide--reset",
    unpinned: "slide--up"

The header variable targets the initial #header ID and stores this element to pass into the Headroom method. This element is all we actually need to initiate the plugin, but some optional parameters allow you to customize the effect.

The first option tolerance is one of two object literals in this set. Basically it takes a list of key/value pairs and passes them into the function or method. The numeric values represent scrolled pixels before the header should re-appear or disappear. So for example once the header slides out of view the user needs to scroll 5px up before it slides back into view.

offset denotes how many pixels from the top should be scrolled before the header initially hides off the screen. This value is important because you may want to adjust based on the size of your own website's header. The following classes option use object literal notation with more key/value pairs.

It's probably easiest to leave these classes alone because they relate directly to the CSS block of animation effects. If you decide to change any of these values be sure to update the class names in your CSS file too.


Not everyone likes these fixed headers but it seems like the trend is here to stay. This design can be effective when implemented properly. Make sure there's always enough space in the layout for free scrolling and readable text. Also, be sure not to hide any content at the top of the page - a little extra padding is a good idea. Feel free to download my sample code and try building this into your own web projects.

Jake Rocheleau

First it was design, then writing, and now affiliate marketing. Over a period of 6-7 years he wrote a lot of content for many websites. You can reach Jake on Twitter.

Get more to your email

Subscribe to our newsletter and access exclusive content and offers available only to MonsterPost subscribers.

From was successfully send!
Server error. Please, try again later.

Leave a Reply