Advertisement
HTML/CSS

A Simple, Responsive, Mobile First Navigation

by

We're going to build a simple, responsive web site navigation. Our solution will help us place emphasis on the content of our page, arguably the top priority when designing for mobile. There'll be no JavaScript involved, and we'll tackle it from a Mobile First approach.


Mobile Navigation

If you've read Luke Wroblewski's Mobile First you'll be familiar with his statement that:

As a general rule, content takes precedence over navigation on mobile.

What he means by this is that mobile users are often looking for immediate answers; they want the content they went searching for, not more navigation options.

Many sites, even responsive ones, stick to the convention that navigation belongs at the top of any given page. This approach can cause usability problems on mobile devices because mobile users are often short of two things: screen space and time. If primary navigation is placed at the top of a page, there's a good chance it will obscure an entire mobile screen. This issue is exacerbated further by large touch-friendly menu links, forcing users to scroll beyond the navigation to get to any valuable content.

Take this example from London & Partners:

A perfectly decent responsive design, but at standard mobile viewport dimensions (320px x 480px) all you really see is a navigation menu. Surely, having just arrived at the homepage, I want to see something other than that? It's not just London & Partners who demonstrate this - it's a practice seen in many responsive designs across the web.


So What are the Solutions?

We've seen a few ways of getting round this, often leaning on jQuery to sort things out for us. Take Chris Coyier's explanation of the Five Simple Steps responsive dropdown menu.


Big screen, little screen.

Using jQuery, a duplicate of the menu is created in the form of a <select> dropdown, initially hidden from view using CSS. When media queries detect a smaller screen, they make the dropdown visible and the original navigation invisible. This is perfect for mobile devices as dropdowns take up minimal real estate and make use of the device's particular UI (like the iPhone's scroller).

Alternatively, you might hide your navigation, but have it transition into view when a 'menu' button is clicked. You can see this effect in action with Twitter's latest Bootstrap.

Smaller screens hide the navigation links and display a 'list' icon (fast becoming accepted as meaning 'menu') which reveals the navigation when clicked. Again, mobile visitors are presented with as much content as possible, but have navigation options available should they want them.


Pure CSS Solution

We're going to use a technique discussed by Luke, which makes use of CSS and a Mobile First approach. What do we mean by a Mobile First approach? Put simply, we're going to design a straight-forward mobile layout, then progressively enhance the design for larger screens. We'll use media queries which detect steadily increasing screen sizes, adding style and features as we go.

This means that only the bear minimum of CSS and resources will be loaded when our design is viewed with a mobile device. It also means that older versions of IE (which don't recognize media queries) will be presented with the mobile site. Check out Joni Korpi's Leaving Old Internet Explorer Behind for more information on this.


Step 1: Markup

I'll explain the ideas behind this solution as we go along, so for the time being let's throw together some markup, starting off with a blanco HTML5 document.

<html lang="en">
<head>

	<meta charset="utf-8">
	<title>Mobile First Responsive Navigation</title>
	<meta name="description" content="CSS only mobile first navigation">
	<meta name="author" content="Ian Yates">

	<!--Mobile specific meta goodness :)-->
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

	<!--css-->
	<link rel="stylesheet" href="styles.css">

	<!--[if lt IE 9]>
		<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
	<![endif]-->

	<!-- Favicons-->
	<link rel="shortcut icon" href="img/favicon.ico">

</head>
<body id="home">

	
</body>
</html>

Note: Don't Forget the Viewport Meta Tag!

Having done that, we'll add some page structure. Straight-forward stuff and all for the purposes of our demonstration. I've used filler text from Monty Python's Holy Grail (thanks Chris Valleskey) which is a nice way to put a smile on your face whilst you're working :)

<body id="home">

	<div class="wrapper">
	
		<header>
		
			<h1 class="logo"><a href="">Nav</a></h1>
		
		</header>
		
		<article>
		
			<h2>Blue. No, yel&hellip;</h2> 
			
			<p>Shut up! Will you shut up?! But you are dressed as one&hellip; Camelot! You don't vote for kings.</p> 
		
		</article>
		
		<article>
			
			<h2>We want a shrubbery!!</h2> 
			
			<p>Look, my liege! Shut up! But you are dressed as one&hellip;</p> 
			
			<ul> 
				<li>The nose?</li> 
				<li>Shh! Knights, I bid you welcome to your new home. Let us ride to Camelot!</li> 
				<li>Look, my liege!</li> 
			</ul> 
		
		</article>
		
		<article>
			
			<h2>Help, help, I'm being repressed!</h2> 
			
			<p>Why? Listen. Strange women lying in ponds distributing swords is no basis for a system of government. Supreme executive power derives from a mandate from the masses, not from some farcical aquatic ceremony. Be quiet! A newt?</p> 
		
		</article>
		
		<footer>
		
			<p>Copyright &copy;2012 Ian Yates <a href="http://webdesign.tutsplus.com">Webdesigntuts+</a></p>
		
		</footer>
	
	</div><!--end wrapper-->
	
</body>

Step 2: Navigation Markup

We've pulled together a basic html page, so now it's time for the main attraction; our primary navigation..

		<nav id="primary_nav">
		
			<ul>
			
				<li><a href="">Portfolio</a></li>
			
				<li><a href="">About Me</a></li>
			
				<li><a href="">Nonsense</a></li>
			
				<li><a href="">Services</a></li>
			
				<li><a href="">Contact</a></li>
			
				<li><a href="#home">Top</a></li>
			
			</ul>
		
		</nav><!--end primary_nav-->

Yes, you've seen that correctly, we've added that at line 68, after the last article. Don't forget that we're designing for mobile now, we'll cover desktop later. We've placed the navigation at the bottom of our page so that it's completely out of the way. We're now going to place a link at the top of our page so that users can find the navigation if they wish.

		<header>
		
			<h1 class="logo"><a href="">Nav</a></h1>
			
			<a class="to_nav" href="#primary_nav">Menu</a>
		
		</header>

Step 3: CSS Reset

Depending on how you normally begin web projects, this step my differ from your usual workflow. I've always found Eric Meyer's reset to be a solid basis to work from, especially as he's tweaked it recently. We'll add his reset rules to a stylesheet to kick our css off:

/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0b1 | 201101 
   NOTE: WORK IN PROGRESS
   USE WITH CAUTION AND TEST WITH ABANDON */

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, figcaption, figure, 
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}

/* remember to highlight inserts somehow! */
ins {
	text-decoration: none;
}
del {
	text-decoration: line-through;
}

table {
	border-collapse: collapse;
	border-spacing: 0;
}

Step 4: Basic Styles

At the moment our page is looking pretty uninspiring..

..so let's improve things by adding some simple styling.

/*begin our styles*/

body {
	font: 16px/1.4em 'PT Sans', sans-serif;;
	color: #1c1c1c;
}

p,
ul {
	margin: 0 0 1.5em;
}

ul {
	list-style: disc;
	padding: 0 0 0 20px;
}

a {
	color: #1D745A;
}

h1 {

}

h2 {
	font-family: 'PT Serif', serif;
	font-size: 32px;
	line-height: 1.4em;
	margin: 0 0 .4em;
	font-weight: bold;
}

/*layout*/

.wrapper {
}

article {
	border-bottom: 1px solid #d8d8d8;
	padding: 10px 20px 0 20px;
	margin: 10px 0;
}

/*header*/

header {
	background: #1c1c1c;
	padding: 15px 20px;
}

		/*shorter clearfix http://nicolasgallagher.com/micro-clearfix-hack/*/
		header:before,
		header:after {
		    content:"";
		    display:table;
		}
		
		header:after {
		    clear:both;
		}
		
		/* For IE 6/7 (trigger hasLayout) */
		header {
		    zoom:1;
		}

h1.logo a {
	color: #d8d8d8;
	text-decoration: none;
	font-weight: bold;
	text-transform: uppercase;
	font-size: 20px;
	line-height: 22px;
	float: left;
	letter-spacing: 0.2em;
}

a.to_nav {
	float: right;
	color: #fff;
	background: #4e4e4e;
	text-decoration: none;
	padding: 0 10px;
	font-size: 12px;
	font-weight: bold;
	line-height: 22px;
	height: 22px;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	-webkit-border-radius: 2px;
	-moz-border-radius: 2px;
	border-radius: 2px;
}

a.to_nav:hover,
a.to_nav:focus {
	color: #1c1c1c;
	background: #ccc;
}

This is all basic stuff (fonts, line-heights, colors etc.), what's crucial so far is that I've styled the 'menu' button to float to the right within the <header>, where you'd often expect navigation to be found.

If you hover over it you'll see the hover state - not necessary for touch screen devices of course, but this experience will also be delivered to uncooperative Internet Explorer versions. What we have defined for the benefit of mobile users is a :focus state. It's the same as the :hover state, but will offer crucial feedback for touch-screen devices. Our users will know they've been successful in touching the menu button.

Anyway, click it and you'll be taken to the navigation, super.

Now let's style the menu a bit.


Step 5: Navigation Styles

We're actually going to style our primary navigation much like the London & Partners example shown earlier on, except this time it's obviously at the bottom of the page..

/*navigation*/	

#primary_nav ul {
	list-style: none;
	background: #1c1c1c;
	padding: 5px 0;
}

#primary_nav li a {
	display: block;
	padding: 0 20px;
	color: #fff;
	text-decoration: none;
	font-weight: bold;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	letter-spacing: 0.1em;
	line-height: 2em;
	height: 2em;
	border-bottom: 1px solid #383838;
}

#primary_nav li:last-child a {
	border-bottom: none;
}

#primary_nav li a:hover,
#primary_nav li a:focus {
	color: #1c1c1c;
	background: #ccc;
}

/*footer*/

footer {
	font-family: 'PT Serif', serif;
	font-style: italic;
	text-align: center;
	font-size: 14px;
}

Much better. We've made the menu links nice and large (read more about Touch Target Sizes on Luke Wroblewski's own blog) and once again determined a :focus state for user feedback.

It's also become clear that we've included a 'top' link which will take users back to the top of the page if needed.


Step 6: Getting Bigger

OK, we've dealt with our simple mobile layout, so now it's time for some progressive enhancement. We're going to use media queries to determine when our mobile layout is no longer appropriate.

But at what point does it become inappropriate? There are many ways to approach media queries, but we're going to work from the basis that a mobile viewport is 320px x 480px. It's 320px wide when viewed in portrait, 480px wide when viewed in landscape, so we could justifiably set our first media query to detect any screen larger than 480px.

However, the next step up is arguably the tablet. The iPad has a resolution of 980px x 768px, so we can safely assume that anything smaller than 768px is appropriate for our mobile layout. Anything larger than 768px can handle more desktop-like navigation layouts.

We can therefore start adding rules, so let's set up a media query:

/*media queries*/

		@media only screen and (min-width: 768px) {
	
		}

This media query will run all styles contained within it when the viewport is at least 768px wide. Note the inclusion of the only keyword, which ensures Internet Explorer 8 doesn't get all confused and try to process the query. See my earlier explanation for details.

Let's kick things off by making our 'menu' button disappear:

		@media only screen and (min-width: 768px) {
		
			a.to_nav {
				display: none;
			}
	
		}

With the browser made slightly wider, the menu button is no longer displayed.


Step 7: Shifting the Navigation

Now we need to bring our primary navigation to the top of the page. We'll do that by removing it from the document flow, positioning it absolutely at the top.

 
		@media only screen and (min-width: 768px) {
		
			a.to_nav {
				display: none;
			}
			
			.wrapper {
				position: relative;
				width: 768px;
				margin: auto;
			}
			
			#primary_nav {
				position: absolute;
				top: 5px;
				right: 10px;
				background: none;
			}
			
			#primary_nav li {
				display: inline;
			}
			
			#primary_nav li a {
				float: left;
				border: none;
				padding: 0 10px;
				-webkit-border-radius: 2px;
				-moz-border-radius: 2px;
				border-radius: 2px;
			}
	
		}

In order for that to be possible we first have to make its parent (.wrapper) relatively positioned. We can either do that here in the media query, or determine that at the beginning of our stylesheet.

Once the menu is positioned absolutely, we need to remove some of the anchor styling. There's not much to do, but we need the list items to display inline, and we need to remove the borders and exaggerated padding from the anchors. The hover states we dictated earlier are fine of course, so we needn't change them.


Step 8: One Last Thing

If you've been paying attention you'll have noticed that we still have a 'top' link in the navigation - we don't really need that any more eh?

We can remove this in a number of ways, but so we're sure of what's going on let's first add a class to the list item:

				<li class="top"><a href="#home">Top</a></li>

And then we can get rid of it within our media query:

			#primary_nav li.top {
				display: none;
			}

Conclusion

That's it! There are loads of ways to build upon this idea (implementing the list icon being just one) and, of course, you can continue to add media queries to cater for growing screens. Hopefully you now have the foundations to do so. We've created a simple, responsive, touch-friendly navigation, from a mobile first approach whilst giving emphasis to content and usability. Who can ask for more?!


Further Resources

A few useful links mentioned in the tutorial, all piled into one handy list:

Related Posts
  • Web Design
    Complete Websites
    Building the Responsive Timeline Portfolio PagePortfolio thumb
    During this tutorial we will be building the fantastic Timeline Portfolio as seen in an earlier tutorial by Tomas Laurinavicius. We will be using some responsive techniques as well as CSS3 animations, Sass and a little bit of jQuery.Read More…
  • Web Design
    HTML/CSS
    Build a Top Bar Off-Canvas Navigation With Foundation 5Foundation menu
    Today, we are going to combine ZURB's Foundation 5 Off-Canvas feature with our top bar navigation. The result will be a nice custom navigation for desktop users and a sleek off -canvas menu for tablet and mobile users. Read More…
  • Web Design
    Case Studies
    How They Did It: Typekit's New HomepageTypekit retina
    Typekit recently redesigned their homepage with some new services in mind. When Typekit joined Adobe, they set out to bring us a new way to handle fonts on the web. Not only did they create a fairly simple way to embed fonts on the web, but they have now officially launched a desktop sync option, which allows Creative Cloud subscribers to sync fonts to their computer directly from Typekit. This has been in a beta form for a while now, and provides a much easier route to local fonts than finding them elsewhere!Read More…
  • Web Design
    UX
    Walk Users Through Your Website With Bootstrap TourTour retina
    When you have a web application which requires some getting used to from your users, a walkthrough of the interface is in order. Creating a walkthrough directly on top of the interface makes things very clear, so that's what we're going to build, using Bootstrap Tour.Read More…
  • Web Design
    Email
    Creating a Simple Responsive HTML EmailEmail new rwd thumb
    In this tutorial I will show you how to create a simple responsive HTML email which will work in every email client, including all the new smartphone mail clients and apps. It uses minimal media queries and a fluid width approach to ensure maximum compatibility.Read More…
  • Code
    Theme Development
    Creating a WordPress Theme From Static HTML: Creating Template FilesCreating wordpress theme from html 400
    In the first part of this series, I showed you how to prepare your HTML and CSS files for WordPress, ensuring the structure would work, the code was valid and that the correct classes were being used. In this tutorial you'll learn how to take your index.html file and split it up into a set of template files for use by WordPress.Read More…