Build a Single-Page Sliding Navigation Bar with jQuery

Many web design studios and freelance portfolios will incorporate the popular single page navigation technique. The benefits of such a layout allows visitors to go through all your main content without needing to reload the website. Additionally this helps to keep the interface very simple and easy to maneuver.

In this tutorial I want to demonstrate how we can build a demo single-page layout with sliding navigation effects. I will be using the jQuery One Page Nav plugin which offers more control onto each of the page elements. Additionally the layout is standards compliant with HTML5 and CSS3 specs and the nav will still load properly in browsers where JavaScript is disabled. If you want to catch a glimpse of the final product we are building check out my demo page below.

Build a Single-Page Sliding Navigation Bar with jQuery

Live DemoDownload Source Code

Constructing the Document

First I want to download a copy of the One Page Nav plugin so we can put all the files together. Inside the zip container you will need a copy of jquery.nav.js and jquery.scrollTo.js. Both libraries are necessary for completing the full effects with sliding animation styles. Now I’ll also be creating our main webpage index.html with some bare essentials.

<!doctype html>
<html lang="en-US">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  <title>Single Page Sliding Navigation Demo</title>
  <meta name="author" content="Jake Rocheleau">
  <link rel="shortcut icon" href="http://vandelaydesign.com/favicon.ico">
  <link rel="icon" href="http://vandelaydesign.com/favicon.ico">
  <link rel="stylesheet" type="text/css" media="all" href="styles.css">
  <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Droid+Sans:400,700|Droid+Serif:400,700">
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script type="text/javascript" charset="utf-8" src="js/jquery.scrollTo.js"></script>
  <script type="text/javascript" charset="utf-8" src="js/jquery.nav.js"></script>
<!--[if lt IE 9]>
  <script type="text/javascript" src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>

I am using a free external font named Droid Serif from Google Web Fonts to enhance the design aesthetics. Also the jQuery library is referenced from Google’s code hosting server to minimize our local documents. Then the final interesting 3rd party script is HTML5shiv which is used for older Internet Explorer browsers. These cannot render newer HTML5 elements properly so we need to include JS codes which will fix these bugs.

Developing Content

Inside the body section we need to split the whole content area into various sections or panels. The top navigation menu will be fixed at all times and this will be removed from the document flow. So I am keeping this navbar separate from the inner content areas.

  <nav id="navigation">
    <ul id="topnav">
      <li class="current"><a href="#home">Homepage</a></li>
      <li><a href="#company">The Company</a></li>
      <li><a href="#portfolio">Client Portfolio</a></li>
      <li><a href="#contact">Contact Us</a></li>
    </ul>
  </nav>

  <div id="content">
    <section id="home">
      <div class="wrapper">
        <!-- some content here -->
      </div>
    </section>
    <!-- BG Image Source: http://www.flickr.com/photos/jepoirrier/8206441823/ -->

    <section id="company">
      <div class="wrapper">
        <h1>About our Studio</h1>
         <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer eget scelerisque augue. Phasellus felis est, lobortis ut luctus commodo, venenatis eget arcu. Integer dolor elit, dictum at scelerisque vitae, semper ac sapien. Ut sed nunc sed eros varius ultrices et in libero.</p>

        <p>Nam a tempor sem. Donec vel mi dui. Suspendisse potenti. Sed adipiscing lorem non erat consequat vulputate. In hac habitasse platea dictumst. Sed pellentesque pulvinar sem non suscipit. Vestibulum cursus lectus ut magna gravida vel molestie diam ornare.</p>

        <p>Donec interdum, magna ut pulvinar aliquet, felis tellus lacinia leo, ullamcorper venenatis nisi lectus et nibh. Cras a lectus eros. Cras nec quam sed ligula ornare malesuada. Etiam volutpat purus sed justo semper vitae hendrerit lectus posuere. Nam et fermentum elit.</p>
      </div>
    </section>

I only copied over the HTML codes for our first 2 sections inside the body content. Notice that each of the link’s HREF values points to the specific ID of each section. This means even with JavaScript disabled the pages will jump down to those areas. We may lose the sliding effect but the website still works properly.

You may also notice how each content section has an inner container with the class .wrapper. Since I am using fixed background images we need to separate the section areas from the internal content. These wrappers will center the content without centering the backgrounds too.

Designing Key CSS Styles

If we can move onto the stylesheet it’ll be easier explaining everything from top-to-bottom. I have started with a large block of CSS resets customized from Eric Meyer’s defaults. You should feel free to copy these for your own project or even save them as a custom snippet.

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-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
html { height: 101%; }
body { font-size: 62.5%; line-height: 1; font-family: Helvetica, Tahoma, Arial, sans-serif; background: #121212; color: #f0f0f0; }

::selection { background: #a2ec39; color: #323232; }
::-moz-selection { background: #a2ec39; color: #323232; }
::-webkit-selection { background: #a2ec39; color: #323232; }

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

h1 { font-family: 'Droid Serif', Georgia, serif; color: #b9caa1; font-size: 3.5em; line-height: 1.45em; margin-bottom: 20px; }

h2 { display: inline-block; font-size: 2.9em; padding: 12px 17px; background: rgba(0,0,0,0.65); color: #fff; font-weight: bold; font-family: Arial, Tahoma, sans-serif; }

p { font-size: 1.55em; line-height: 1.35em; padding: 2px 0; margin-bottom: 15px; }

The font smoothing properties are only useful on Mac OSX or iOS systems where they can be applied. Also the -webkit-text-size-adjust property will help on mobile devices when switching from portrait to landscape will sometimes readjust your fonts. I have this property disabled so we can run a fixed mobile-responsive layout as needed(or not needed).

Now the navigation menu should also be fixed onto the top of the page as the user scrolls down. I want to setup a specific height value which will keep the text links at an even line-height. The navbar background is semi-transparent using the rgba() color syntax.

/* top navigation */
#navigation {
  display: block;
  position: fixed;
  top: 0px;
  width: 100%;
  height: 70px;
  background: rgba(255,255,255,0.75);
  z-index: 9999;
}
#topnav {
  max-width: 900px;
  min-width: 380px;
  margin: 0 auto;
  font-family: 'Droid Sans', Helvetica, Arial, sans-serif;
  clear: both;
}

#topnav li a {
  display: block;
  float: left;
  color: #53574d;
  padding: 0px 11px;
  margin-right: 15px;
  font-size: 1.6em;
  line-height: 70px;
  font-weight: bold;
  text-decoration: none;
  -webkit-transition: all 0.5s linear;
  -moz-transition: all 0.5s linear;
  transition: all 0.5s linear;
}
#topnav li a:hover {
  color: #7d8079;
  background: rgba(255,255,255,0.65);
}

#topnav li.current a {
  background: rgba(255,255,255,0.7);
  color: #90ae64;
  border-bottom: 4px solid #b9dc8c;
}

Each of the links is using CSS3 animation transitions on hover. The links will animate a clearer background color which also uses alpha-transparency. So we never have a full 100% white background but the text is always legible. All of the padding and extra space is applied onto the anchor links so that visitors have an easier time clicking between sections.

/* main content sections */
#content { display: block; width: 100%; overflow: hidden; }

.wrapper {
  display: block;
  width: 800px;
  min-width: 380px;
  margin: 0 auto;
}

#home {
  background: url('images/office-space-bg.jpg') no-repeat center center;
  background-attachment: fixed;
  -webkit-background-size: cover;
  -moz-background-size: cover;
  -o-background-size: cover;
  background-size: cover;
  min-height: 550px;
  padding-top: 85px;
  margin-bottom: 40px;
  box-shadow: inset 1px -9px 20px -6px #000;
}

This is the last important set of properties we need to look into for our final layout. The #content div is referencing the outermost container for all of the internal sections. We need to use overflow: hidden; to handle excess content as the window is resized smaller than the inner text areas.

Another interesting bit of code is applied onto the #home section. This is the very first part of the webpage you will notice when everything finishes loading. I have added a fixed background image which scales the full width of its container. This same BG image style is found in another section a bit lower down the page. My original codes are based off the CSS3 model but there are some alternatives using jQuery. For this demo I figured it would be easier to stick with newer methods and keep our external resources to a minimum.

Applying the jQuery

Moving onto our final stage we can add the small block of JavaScript required to get this whole navigation working. All we need to do is define the navigation selector along with a few unrelated function parameters.

<script type="text/javascript">
$(document).ready(function(){
  $('#topnav').onePageNav({
    currentClass: 'current',
	  scrollOffset: 0
  });
});
</script>

You will find this <script> block at the very bottom of my HTML page before the closing body tag. Notice that my selector is referencing #topnav which is the unordered list element and not the nav container. You will always want to select the element which directly contains all the anchor links inside.

The two parameters I am passing should not be necessary to get everything working right away. currentClass will append a class name onto the current list item as it comes into view. The offset parameter allows control over where the animation will stop sliding. This comes in handy if the nav menu takes up a considerable portion of the screen and you need to leave some extra padding. I have left this value at 0 but you can toy around and see how it works. Additionally I have copied over the default parameters template found in the plugin documentation.

$('#nav').onePageNav({
    currentClass: 'current',
    changeHash: false,
    scrollSpeed: 750,
    scrollOffset: 30,
    scrollThreshold: 0.5,
    filter: '',
    easing: 'swing',
    begin: function() {
        //I get fired when the animation is starting
    },
    end: function() {
        //I get fired when the animation is ending
    },
    scrollChange: function($currentListItem) {
        //I get fired when you enter a section and I pass the list item of the section
    }
});

But to reiterate, these parameters are not necessary for the plugin to work. That is why the codes are built with default settings! However I know developers love to dig deeper into these open source plugins – so feel free to customize to your liking.

Build a Single-Page Sliding Navigation Bar with jQuery

Live DemoDownload Source Code

Final Thoughts

I hope this tutorial may be useful to at least a few web developers. The single page technique is very popular and it is gaining momentum very quickly. I have been noticing this effect added into websites more frequently over the past couple of years. And with the possibilities of open source plugins it has never been easier to get a template up and running.

Take a look at my live demo project and feel free to download a copy of the source codes. All my tutorials are released under no general license and completely free to modify/duplicate for your own websites. The One Page Nav plugin has additional options which you can find on the Github repo. If you have any further questions or ideas please let us know in the discussion area.

About the Author:

Jake is a freelance writer and frontend web developer. He can be found writing in many blogs on topics such as mobile interfaces, freelancing, jQuery, and Objective-C. Check out his other articles throughout Google and follow his tweets @jakerocheleauJake’s Google+ profile.

Published March 13th, 2013 by

Looking for hosting? WPEngine offers secure managed WordPress hosting. You’ll get expert WordPress support, automatic backups, and caching for fast page loads. Visit WPEngine.

Join Our Newsletter!

Subscribe to our weekly newsletter chalked full of useful tips, techniques, and design goodies. We have 20,000+ loyal readers and counting! We’ll even send you a free e-book (Freelance Designer’s Guide to Multiple Income Streams) and a $10 discount on our most popular product the Freelance Starter Kit.

15 Responses

Comments are now closed on this post.

  • Awais Raza, March 13, 2013

    Good tutorial. but there is little thing missing. In start it must be placed at somewhere, but when scroll down , on some position it might stick on top. While a good tutorial anyways.

  • Srinivas Reddy, March 14, 2013

    Nice Article…Thank you a lot for sharing!!

  • Julian, March 14, 2013

    How did you handle the transition from one full-screen background to the next? That was the main thing I was looking to learn here, and I think you didn’t cover it (or did I miss something?).

  • Jake Rocheleau, March 18, 2013

    @Julian the transitions happen automatically when you click the navigation bar links. the plugin will automatically determine the next fullscreen background based on the container IDs.

  • Omakr Bhide, March 20, 2013

    Hey Jake thanks…..
    surely this post is very helpful of every designer ……as i can feel after being a designer…

  • Parveen Kaushik, March 21, 2013

    Hi Jake :)

    This Article is very helpful. Thanks for sharing

  • Michael, March 21, 2013

    Great article! Would have loved this info a few weeks ago. I just finished up a similar project. Turned out nice, but a few shortcuts would have been helpful.

  • David, April 8, 2013

    Thanks so much! It’s a very useful tutorial.

  • hetal, April 10, 2013

    Hi

    I tried this script in my website but on clicking menu its stops much below the actual start of the page.So the heading of the page is hidden above.

    Also when I load webpage it shows about page as default and not first index page.

    What to do to rectify the problem.

    Regards
    Hetal

  • heinrich klassen, April 17, 2013

    Hi and thank you very much for this tutorial!

    Works perfect!
    Exept: in safaribrowser at iPad i cannot tap any menu-element after having tapped another.
    Do you have any ideas, why this could be?

    Thanks!

    Heinrich

  • Jim, May 8, 2013

    Hey Jake
    Thank you for this tutorial. It answers a problem I’ve been having for a new website.

    It’s a nice, slim and elegant solution for a one page web design.

  • Chris Thom, June 18, 2013

    Nice tutorial.

    If I wanted to add a “next” button at the bottom of each section could you do that while still having the smooth scrolling and nav highlighting?

  • luchid, July 9, 2013

    This is a great tutorial, thank you for sharing it. I have though a question. I want to implement a sliding navigation bar into WordPress and I need to use WordPress Pages instead of . Is there a way to do this? I have little experience with JavaScript, so I do not know how to make it work. Thank you very much!

  • Felipe, July 13, 2013

    Thank you, Mr Jake.

    This is awesome.

  • Carlos, September 26, 2013

    Thank you very much. That’s exactly what I was looking for