Creating A Simple Responsive Navigation

Written by Paula Borowska on 07 May 2013
58,160 Views • Tutorials

This tutorial is designed to show you how to create a simple, responsive navigation. By no means is this tutorial hard – it too is simple and straightforward. I will be going over everything that goes into making this responsive navigation, so that you have a solid understanding of what is going on.

Before starting to code anything, I think it is very important to know what it is you are building. Below you'll find photos of what this responsive navigation will look like. It has two different looks: one of spread out links like a typical desktop navigation is, and, another look of an accordion that will be used for the mobile versions. Like I said, this is a very simple and clean navigation.

HTML

First things first, we need to define the HTML structure of the navigation. As you can see, the code below is HTML5. You should place it within the body of your HTML5 document. There are six links with arbitrary names that link to different sections within the same document. They are named one through six for easy comprehension. Additionally, in the nav tag you see that outside the unordered list is another link. This is the link that will be visible for mobile versions of this navigation.

<nav>
	<ul>
		<li><a href="#one">Intro</a></li>
		<li><a href="#two">Summary</a></li>
		<li><a href="#three">Skills</a></li>
		<li><a href="#four">Experience</a></li>
		<li><a href="#five">Education</a></li>
		<li><a href="#six">Contact</a></li>
	</ul>
	<a href="#" id="pull">Menu</a>
</nav>	

Now that this is done with, it is time to create the different sections for the links to travel to. For now, nothing won't be happening when you click, as the sections aren't defined or filled for anything to happen.

<section id="one"></section>
<section id="two"></section>
<section id="three"></section>
<section id="four"></section>
<section id="five"></section>
<section id="six"></section>

CSS

Like with any other CSS, you can link an external file in or, to keep things simple, place it in the head of the document so that you don't have to flip between different files.

Now, let's start the CSS styling by defining the shape of the six sections we just created. As you can see they are the same with the only difference being their background colour. This should be very easy to copy one by one in. The sections don't really need to be any more different as for now they are only there to help indicate that the navigation is actually working and jumping from one section to the next – which you can clearly see by the changes in colour.

/* Div Styling */
#one{
	width: 100%;
	height: 250px;
	background: #9FF;
}
#two{
	width: 100%;
	height: 250px;
	background: #9F6;
}
#three{
	width: 100%;
	height: 250px;
	background: #9F0;
}
#four{
	width: 100%;
	height: 250px;
	background: #CF0;
}
#five{
	width: 100%;
	height: 250px;
	background: #CF9;
}
#six{
	width: 100%;
	height: 250px;
	background: #F93;
}	

Before we style the navigation, I want to add a little trick called clearfix. What it does is help display an element, usually a div or a section, as a block no matter what. Sometimes when you write CSS things get messed up – especially when you use the float property. In this case the clearfix won't do much as there isn't a lot going on, but it is a good practice to use it in the most important element, like the navigation.

/* Clearfix */
.clearfix:before,
.clearfix:after {
    content: " ";
    display: table;
}
.clearfix:after {
    clear: both;
}
.clearfix {
    *zoom: 1;
}	

Now let's add the clearfix class to both the nav section and the ul.

<nav class="clearfix">
	<ul class="clearfix">

Perfect. Now we can focus on styling the navigation itself. As you can see in the following code, there isn't much to this navigation. It is a dark gray rectangle that hangs onto the top of the page. You can fiddle with the style as you wish; the only thing you should keep constant is that the li's ought to be on the same line, like in the example. The other thing is that the link I've pointed out earlier (the one outside of the unordered list) should be hidden while a user is viewing this site on a larger screen.

/* Navigation */
nav {
	height: 40px;
	width: 100%;
	background: #262626;
	font-size: 11pt;
	position: fixed;
	top: 0;
	
}
nav ul {
	padding: 0;
	margin: 0;
	height: 40px;
}
nav li {
	display: inline;
	float: left;
}
nav a {
	color: #fff;
	display: inline-block;
	width: 100px;
	text-align: center;
	text-decoration: none;
	padding:9px 0;
}
nav a#pull {
	display: none;
}	

Thanks to CSS3, we can implement a media query to make this navigation, in fact, responsive. What is happening below is you are defining a new set of CSS rules that will override or be added in addition to, the already in place CSS if the criteria is met. In this query the criteria is that if the screen's width is at maximum 800px, then use the following code.

When you are placing CSS within media query you need to be aware that you need to explicitly say what it is you want to happen. For instance, if you want the width of an element to be 100px instead of 40px, you'd write 'width:100px'. However, if you no longer want an element to float right, you would need to specify that its float is now none because otherwise it would assume you still want it to float right. This is exactly what is going on in the code below. Take a look at it and see that this is exactly what is going on in the media query below.

@media screen and (max-width: 800px) {
	nav {
		height: auto;
		border-bottom: 0;
	}
	nav ul {
		display: none;
		height: auto;
	}	
	nav li {
		width: 100%;
		float: left;
		position: relative;
		border-bottom: 1px solid #262626;
  	}

  	nav a {
	  	text-align: left;
	  	width: 100%;
	  	text-indent: 25px;
			background: #2e2e2e;	  	
  	}  	
  	nav a:hover {
	  	background:#444;
  	}
  	  		
	nav a#pull {
		display: block;
		background-color: #262626;
		width: 100%;
		position: relative;
	}
	nav a#pull:after {
		content:"";
		background: url(nav-icon.png) no-repeat;
		width: 30px;
		height: 30px;
		color: #FFF;
		display: inline-block;
		position: absolute;
		right: 15px;
		top: 10px;
	}
}	

Making it work

In order for this navigation to work you will need one more thing, which is jQuery to animate the mobile navigation. As of right now, the navigation is resizing but nothing is happening when you click the mobile navigation's menu link. So, let's fix it.

Within the head of your document, include a link to jQuery's library. Without it, the code we are about to include is not going to work; it is simply the way jQuery works. If you want to, you could download the file and include a link to it locally. It is actually better practice, but for this tutorial it is unnecessary.

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

Now we can write some jQuery. Below you'll find that the code is very short and sweet. Basically what is happening is we are animating the menu link to literally toggle up and down when you click it. On top of that, when the menu link is down, the listed links become visible. If you know your way around jQuery you could add a bunch of cool effects to this toggle such as an animation effect or speed of toggle. It is all up to you.

$(function() {
		var pull 		= $('#pull');
				menu 		= $('nav ul');

		$(pull).on('click', function(e) {
			e.preventDefault();
			menu.slideToggle();
		});
		
		$(window).resize(function(){
			var w = $(this).width();

			if(w > 800 && menu.is(':hidden')) {
				menu.removeAttr('style');
			}
		});

		$('li').on('click', function(e) {				
			var w = $(window).width();
			if(w < 800 ) {
				menu.slideToggle();
			}
		});

		$('.panel').height($(window).height());
		
	});	
Demo Download
Join the discussion

Comments will be moderated and rel="nofollow" will be added to all links. You can wrap your coding with [code][/code] to make use of built-in syntax highlighter.

15 comments
sabari 11 years ago
Good tutorial. But you forgot to close the section tag properly.
Reply
Kevin Admin 11 years ago
Fixed it. Thanks :)
Reply
Jonath Lee 11 years ago
Weird, menu not working in Firefox, Chrome on Win7.

Btw, <meta name="viewport" content="width=device-width"> necessary for mobile viewing?
Reply
Kevin Admin 11 years ago
You're right, I have updated the demo and file.
Reply
uma 11 years ago
This menu is not supported for window OS Why ?

Reply
Stig Rasmussen 11 years ago
Great example - I really like the fact that it's short and clean. However I did find it a bit odd that the demo is different from the code snippets. Most of the differences are self-explanatory but I think it would be a good idea to add the class "panel" to all sections or change the last line in the jquery snippet from
$(".panel")
to
$("section")
so that the section color is rendered correctly.
Reply
orange county web designer 11 years ago
Great tutorial both for its quality and content. Great thinking about mobile overall. Thanks for sharing.
Reply
arnold 11 years ago
thanks for the share

however , just some little corrections :)

at the js code , it should have comma
var pull = $('#pull'),
menu = $('nav ul');


and in the post , it says <section> while the demo uses <div>

Reply
Sebastián Jaramillo 11 years ago
There are a bunch of things you can do to improve this tutorial. Here are some suggestions...

Do this exercise with a Mobile First (Progressive Enhancement) approach, starting with a mobile base and scale up from there. This means rewriting your media queries with min-width instead.

Be proportional with your media queries, use ems instead of pixels. Here is a good article by Liza Gardner of Cloud Four that illustrates the importance of doing this: http://blog.cloudfour.com/the-ems-have-it-proportional-media-queries-ftw/

Regarding your jQuery, the biggest improvement should be the way you check for the window size. Instead of doing this:


if(w > 800 && menu.is(':hidden')) {
...
}


Use Modernizer's media query tester to test for the same media query you use in your CSS, like this:


if (Modernizr.mq('screen and (min-width: 50em)')) {
// 50em considering a 16pm base font-size
// 800px / 16px = 50em
...
}


Read Modernizr's documentation on the topic here:
http://blog.cloudfour.com/the-ems-have-it-proportional-media-queries-ftw/

Anyways... hope this helps to get this to the next step.
Reply
bucur 11 years ago
nice tutorial,but nobody thinks and a version for wordpress.I searched but nothing.
Reply
Najima 11 years ago
Thank you very much ! I was looking for a simple tutorial like this ! Tks ! :D
Reply
Avinash 11 years ago
I love to help people like you to build your first responsive theme: http://responsivetools.com
Reply
Karl 10 years ago
This is cool, thanks for this.

I'm having a bit of a problem though, when I tried it, my navigation remains visible when ever I go to another page on mobile. It only disappears when I click the menu button.

Am I missing something?
Reply
Karl 10 years ago
Ignore previous comment; figured it out.

Thanks
Reply
jim cougar 9 years ago
nice work, saved me hours of head scratching, my menu remains open when I resize my browser, I have implemented it into my nav structure but I think im missing something, lol@karl the usual response when finding out how to fix is to post the solution so that it can help others and maybe even yourself if you run into it again, thx karl lol any ideas anyone?
Reply