Simple Steps for Creating a Fixed Navigation Bar

When designing a navigation system for your website it is important to consider dynamic alterations for handling mobile support and responsive designs. But another systematic approach is to keep your visitors in full control throughout the entire viewing process. This often requires a quick-to-access menu or dropdown area for pulling links to other webpages.

In this tutorial I’m going to be building a top navigation bar which appears only after moving beyond the header navigation. This effect is great if you have a few pages which are most commonly accessed by visitors. The sticky navbar will stay fixed at the top of the screen and only disappear when re-entering the header nav zone. To get an idea of what we will be making check out my live demo example after the jump!

19+ Million Digital Assets, With Unlimited Downloads

Get unlimited downloads of 19+ million design resources, themes, templates, photos, graphics and more. An Envato subscription starts at $16 per month, and is the best unlimited creative subscription we've ever seen.

Explore Digital Assets

Live DemoDownload Source Code

Structuring the Document

First we should create the project workspace and build the original HTML code. It’s worth noting we will need to use some very basic jQuery along with the CSS effects.

Create a new set of documents named index.html and styles.css within the same directory. I am using a custom background image and logo banner in the header section. You may download these resources along with my source code if you want to save time. Now in the main index file we need to setup an HTML5 doctype plus add the related links.

<!doctype html>
<html lang="en-US">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  <title>Fixed Top Navigation Toolbar</title>
  <meta name="author" content="Jake Rocheleau">
  <link rel="shortcut icon" href="https://designshack.net/favicon.ico">
  <link rel="icon" href="https://designshack.net/favicon.ico">
  <link rel="stylesheet" type="text/css" media="all" href="styles.css">
  <link rel="stylesheet" type="text/css" media="all" href="http://fonts.googleapis.com/css?family=Capriola">
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>

Thankfully a lot of the resources we need can be hosted externally. Our custom Google web font named Capriola styles the header text and we also need a copy of the latest jQuery library hosted from Google’s code CDN. Most of this should be familiar so let’s now jump into the body content.

HTML Building Blocks

The layout isn’t as complicated as you might first think. At the very top after opening the body tag we need to setup the fixed navigation bar. This element will use display: none; to initially stay hidden until after scrolling a bit down the page.

  <nav id="fixedbar">
    <ul id="fixednav">
      <li><a href="#">Homepage</a></li>
      <li><a href="#">About Us</a></li>
      <li><a href="#">Community</a></li>
      <li><a href="#">Staff Members</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>

The inner UL element will center all the links so they are in the same location as the main content. Then underneath this navbar we setup the main wrapper div which centers the page at 710px width, minus 30px for padding. The total comes out to 680px which is the perfect size for Pontus Johansson’s freebie used in the banner design.

  <div id="w">
    <header id="logo"><a href="index.html"><span id="logobg">SomeWebsiteLogo</span></a></header>
    
    <nav id="navigation">
      <ul>
        <li><a href="#">Homepage</a></li>
        <li><a href="#">About Us</a></li>
        <li><a href="#">Community</a></li>
        <li><a href="#">Staff Members</a></li>
        <li><a href="#">Contact</a></li>
      </ul>
    </nav>
    
    <div id="content">
    <!-- content here -->
    </div>
  </div>

The main navigation bar has the exact same links as we are keeping in the fixed header bar. This was made so by design, however you could change things up and place only the most important links in your fixed navigation. The header may contain dropdowns which also feel out of place in a sliding fixed navbar.

Customizing CSS

Before handling the brief snippet of JavaScript let me explain how we can style all this code. First I am using a more customized style of resets based off Eric Meyer’s original stylesheet. I have defined the box-sizing property as border-box so that exact width values include margin/padding and not expand, as is the default behavior.

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
  outline: none;
  -webkit-text-size-adjust: 100%;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
html { height: 101%; }
body { font-family: Tahoma, Verdana, Arial, sans-serif; font-size: 62.5%; line-height: 1; padding-bottom: 65px; background: #444 url('images/bg.png'); }

article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; }
ol, ul { list-style: none; }

blockquote, q { quotes: none; }
blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; }
strong { font-weight: bold; } 

table { border-collapse: collapse; border-spacing: 0; }
img { border: 0; max-width: 100%; }

The background image is using Debut Dark from the Subtle Patterns website. There are a lot of fantastic repeating textures you can download for free to improve the quality of your layouts. But moving onto the core structure we need to setup a wrapper container so it will fill naturally in the center content. Also the background should appear white in the content area but not in the full header section.

#w {
  display: block;
  width: 710px;
  padding: 14px 15px;
  margin: 0 auto;
  margin-top: 45px;
}

#content {
  display: block;
  background: #fff;
  padding: 14px 20px;
}

#logo { display: block; border: 1px solid #232323; border-bottom-width: 0; }
#logobg { 
  display: block;
  width: 100%;
  height: 130px;
  background: url('images/logo.png') top left no-repeat;
  text-indent: 100%;
  white-space: nowrap;
  overflow: hidden;
}

/* top navigation */
#navigation {
  display: block;
  height: 35px;
  background-color: #131313;
  background-image: -webkit-gradient(linear, left top, left bottom, from(#202020), to(#131313));
  background-image: -webkit-linear-gradient(top, #202020, #131313);
  background-image: -moz-linear-gradient(top, #202020, #131313);
  background-image: -ms-linear-gradient(top, #202020, #131313);
  background-image: -o-linear-gradient(top, #202020, #131313);
  background-image: linear-gradient(top, #202020, #131313);
}

#navigation ul { list-style: none; padding: 0px 7px; }

#navigation ul li { display: inline; float: left; }
#navigation ul li a { 
  display: block; 
  padding: 0 8px; 
  color: #fff;
  font-size: 1.1em;
  text-decoration: none;
  line-height: 35px; 
  font-weight: bold; 
  margin-right: 6px;
  text-shadow: 1px 1px 1px #000;
  -webkit-transition: all 0.2s linear;
  -moz-transition: all 0.2s linear;
  transition: all 0.2s linear;
}
#navigation ul li a:hover { color: #a8d6e7; }

I have setup a very colorful repeating background gradient on the main navigation menu. Also using a fixed height for the bar we can setup the same fixed value for line-height properties on the list items. This forces all text to be centered vertically within the navbar container. I’ve included a few CSS3 transition properties for handling a more sleek hover state.

Fixing the Hidden Navbar

At the very bottom of our CSS stylesheet you will find all the codes related to our fixed top navigation. The container spans 100% of the page width so that we see the bar appear across the whole screen. But the internal UL object holds all the links centered at the same position as our content. Also the background color is applied using rgba() syntax for alpha-transparency.

/* hidden fixed navigation */
#fixedbar { 
  display: none;
  position: fixed;
  top: 0;
  width: 100%;
  height: 80px;
  background: rgba(0,0,0,0.75);
}

#fixednav { 
  display: block;
  width: 710px;
  margin: 0 auto;
  padding: 0px 25px;
}

#fixednav li a {
  display: block;
  float: left;
  font-size: 1.75em;
  font-weight: bold;
  color: #96aed8;
  line-height: 80px;
  text-decoration: none;
  padding: 0px 8px;
  margin-right: 6px; 
  -webkit-transition: all 0.2s linear;
  -moz-transition: all 0.2s linear;
  transition: all 0.2s linear; 
}
#fixednav li a:hover {
  color: #fff;
  background: rgba(0,0,0,0.3);
}

Again we can see a fixed height at 80px which is fairly large in comparison to the original. But it does catch your attention and the links are very easy to maneuver. I wanted to keep a similar animation effect using CSS3 transitions on hover. So the links fill in another 30% background which appears darker, but still transparent for the content behind it.

Handling JavaScript Animations

I am looking at the very bottom of our index.html file before the final closing tag. Here I want to add a small bit of JavaScript which will handle the scrolling effects for displaying and hiding the fixed navbar. We can break it down line-by-line for the more complicated stuff.

<script type="text/javascript">
$(document).ready(function(){
  $('#navigation a, #fixedbar a').on('click', function(e) {
    e.preventDefault();
  });
  
  $(window).on('scroll',function() {
    var scrolltop = $(this).scrollTop();

    if(scrolltop >= 215) {
      $('#fixedbar').fadeIn(250);
    }
    
    else if(scrolltop <= 210) {
      $('#fixedbar').fadeOut(250);
    }
  });
});
</script>

The typical jQuery call pauses execution for the DOM to finish rendering before running any codes. We can also ignore the first block which uses the line e.preventDefault(); for stopping anchor links from loading. The most important stuff is handled inside the event listener for $(window).on('scroll') which is firing a new function every time the user scrolls up or down.

The variable “scrolltop” contains the value in pixels from the very top of the screen. This will update every time the user scrolls to a new location. Using this value we can check if the user has scrolled beyond 215px and if so, display the hidden navbar. On the other hand if they scroll up at 210px or less then we know the main header navigation bar is coming into view, so we hide the fixed navbar and clear up the screen space.

fixed-scrolling-navigation-demo-preview

Live DemoDownload Source Code

Final Thoughts

Although this is a relatively simple effect the code may be confusing if you are unfamiliar with JavaScript. Spend a bit of time going over my snippets to ensure that you understand how we are displaying and hiding the menu. Also feel free to download a copy of my project source code and toy around on your own. If you’d like to drop any questions or comments on this tutorial let us know in the post discussion thread.