facebook twitter
Webucator's Free Responsive Web Design Training Tutorial

Lesson: Mobile Menus

Welcome to our free Responsive Web Design Training tutorial. This tutorial is based on Webucator's Responsive Web Design Training course.

In this lesson, you will learn about Mobile Menus.

Lesson Goals

  • Learn how design patterns for presenting navigation elements differ between desktop and mobile views.
  • Learn strategies for developing mobile-friendly navigation.

Mobile Menus

Desktop views of web pages typically present navigation elements in horizontal or vertical fashion. It's something with which we've become quite familiar: a horizontal bar, say, of seven or so items - "About Us", "Products", "Services", etc. - spans the width of the page underneath the main logo and shows drop-down elements when moused over. Perhaps another smaller horizontal nav menu ("News", "Contact", etc.) sits at the top of the page. These nav bars give visitors to the site a useful means of finding desired content.

A mobile view of the same content still needs to present these way-finding elements but now, of course, we have less screen real estate with which to work. A seven- or eight-across horizontal nav bar won't work quite as well, since each individual nav element would need to be proportionally smaller and might, as a result, be too small to read and too small to tap.

With the explosion of the use of mobile devices to access the web in recent years, we've seen some standardization in how navigation elements are presented. Perhaps the most common is to collapse the horizontal nav bar into a single "menu" icon - often displayed as three horizontal bars - on which the user can tap to toggle the menu.

Let's look at an example. https://alistapart.com/, the popular web magazine which "explores the design, development, and meaning of web content, with a special focus on web standards and best practices", presents desktop visitors with a horizontal navigation menu at the very top of the page, somewhat (in a "designy" fashion) obscuring the site's logo:

Alistapart Navigation Menu

Mobile viewers see the same semi-transparent white horizontal bar at top. However, the menu is now collapsed; users can toggle the menu by tapping the three-horizontal-bar icon at upper left. Here are two views of the mobile style of the site, with the left view showing the initial state and the right view showing the menu expanded, after the user has tapped the menu icon:

Two Views of Mobile Navigation Menu

A variety of design patterns have, in recent years, emerged as useful ways to handle delivering navigation elements to mobile users: toggling a menu (like the https://alistapart.com/ example above), toggling a menu affixed to the footer, sliding out a menu from the side, etc. How you decide to design your menu is, of course, up to you and depends on the specifics of your site's design, audience, and goals.

A First Example

CSS media queries will be, of course, at the center of our work here: we can detect features of our visitor's devices - viewport width in particular. We already present the menu on our Jazz Calendar site differently for mobile users: a CSS media-query rule

@media screen and (max-device-width: 480px) {
	nav ul li a {
		display:block;
		padding:4% 0;
		border-bottom:1px solid #000;
	}
}

displays navigation vertically with borders for folks coming to our site from a device with max viewport width of 480 pixels:

Mobile Jazz Calendar Menu

By sprinkling in a bit of jQuery code and updating our CSS slightly, we can present users with the toggle menu icon, hiding the navigation initially but allowing users to tap to see the nav. We do so in the next example.

Code Sample:

MobileMenus/Demos/jazzresponsivemenu/index.html
<!DOCTYPE html>
  <html>
  <head>
    <title>Jazz Calendar - Local Live Jazz Music Events</title>
    <link rel="stylesheet" type="text/css" href="css/reset.css" />
    <link rel="stylesheet" type="text/css" href="css/style.css" />
    <link rel="apple-touch-icon" href="images/jazzicon.png" />
    <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script type="text/javascript">
      
      $( document ).ready(function() {
        $( "#mobilemenutoggle" ).click(function() {
          $( "nav ul" ).toggle();
          return false;
        });
      });
  
    </script>
    <meta name="viewport" content="initial-scale=1.0, width=device-width" />
  </head>
  
  <body>
    <div id="container">
    <div id="main">
      <header>
      <img src="images/logo.gif" alt="Jazz Calendar" />
      <h3 id="tagline">Local jazz info</h3>
      </header>
      <nav>
      <a href="#" id="mobilemenutoggle">☰ <span>menu</span></a>
      <ul>
      <li><a href="index.html">Home</a></li>
      <li><a href="performances.html">Performances</a></li>
      <li><a href="about.html">About</a></li>
      <li><a href="contact.html">Contact</a></li>
      </ul>
      </nav>
      <div id="maincontent">
        <article>
        <h2>Mobile Menu!</h2>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
        quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
        consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
        cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
        proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
        </article>
      </div>
      <aside id="sidebar">
        <h3>Signup</h3>
        <p>Become a member of Jazz Calendar now! <a href="#">Email us</a> to receive frequent notices on upcoming live shows.</p>
      </aside>
      <footer id="contactinfo">
      <p>Jazz Calendar
      <br />123 Fake Street, Sometown, USA | 555-123-4567</p>
      </footer>
    </div>
    </div>
  </body>
  </html>

Code Explanation:

Open MobileMenus/Demos/jazzresponsivemenu/index.html in a mobile browser and in a code editor to view the code. Also open the associated CSS file, MobileMenus/Demos/jazzresponsivemenu/css/style.css, in a code editor.

Users who visit this page from a phone initially see the navigation element hidden:

Hidden Navigation Element

Tapping the menu icon toggles the navigation, pushing the other content down:

Toggled Navigation

Conveniently, there exists an HTML character, &#9776;, that gives exactly the three-horizontal-bars icon we want here. Of course, we could have used a small graphic for this instead.

We use some CSS to style the menu icon and to hide the navigation for small viewports:

#mobilemenutoggle {
	display:none;
	text-decoration: none;
	color:#fff;
	font-size:22px;
}

#mobilemenutoggle span {
	font-size:14px;
}

@media screen and (max-device-width: 480px) {
	#mobilemenutoggle {
		display:block;
	}
	nav ul {
		display:none;
	}
	nav ul li a {
		display:block;
		padding:4% 0;
		border-bottom:1px solid #000;
	}
}

The #mobilemenutoggle link is hidden for large viewports (greater than 480 pixels) and, via the media query, displayed for smaller viewports. We use the same media query to hide the unordered list contained within the nav element.

We use jQuery (just jQuery, that is, not jQuery Mobile) code to handle click events on the #mobilemenutoggle link: users who tap the "menu" icon trigger the click method which, in turn, toggles the visibility of the unordered list inside of the nav element. jQuery's toggle does exactly what we want: each successive tap hides or shows the navigation element.

Slicknav: A Mobile Menu jQuery Plugin

A number of jQuery plugins exist to make easier the process of making menus mobile friendly. The benefit of using these plugins - prepackaged jQuery code which you simply call from your page, after linking downloaded script and CSS files - is that you can quickly and easily enable some cool functionality. A potential drawback is that these plugins make some assumptions about how the mobile menu should look and behave, those most come with a set of parameters for customization; you can always, of course, modify CSS to achieve a desired look.

We will look at Slicknav, a popular jQuery mobile-menu plugin. We can see how Slicknav works by checking out their site itself - which, when viewed from a desktop browser, looks like this:

Slicknav from Desktop Browser

From a mobile device or with a browser sized more narrowly, the site looks like this:

Slicknav from Mobile Device

Slicknav simply takes an existing menu - an unordered list that we specify - and adds a copy of it for use as a mobile menu; Slicknav's CSS styles the mobile-view menu which is, by default, fixed to the top of the page. We write our own media queries to handle which menu (desktop or mobile) shows at what viewport width threshold.

To use Slicknav, we download the archived set of needed files (or clone from the projects GitHub page), include them on our page, and add our own media query. Let's look at Slicknav through an example.

Code Sample:

MobileMenus/Demos/jazzslicknav/index.html
<!DOCTYPE html>
<html>
<head>
	<title>Jazz Calendar - Local Live Jazz Music Events</title>
	<link rel="stylesheet" type="text/css" href="css/reset.css" />
	<link rel="stylesheet" type="text/css" href="css/slicknav.css" />
	<link rel="stylesheet" type="text/css" href="css/style.css" />
	<link rel="apple-touch-icon" href="images/jazzicon.png" />
	<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
	<script src="js/jquery.slicknav.min.js"></script>
	<script type="text/javascript">
		
		$( document ).ready(function() {
			$('nav ul').slicknav();
		});

	</script>
	<meta name="viewport" content="initial-scale=1.0, width=device-width" />
</head>

<body>
	<div id="container">
	<div id="main">
		<header>
		<img src="images/logo.gif" alt="Jazz Calendar" />
		<h3 id="tagline">Local jazz info</h3>
		</header>
		<nav>
		<ul>
		<li><a href="index.html">Home</a></li>
		<li><a href="performances.html">Performances</a></li>
		<li><a href="about.html">About</a></li>
		<li><a href="contact.html">Contact</a></li>
		</ul>
		</nav>
		<div id="maincontent">
			<article>
			<h2>Mobile Menu!</h2>
			<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
			tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
			quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
			consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
			cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
			proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
		  </article>
		</div>
		<aside id="sidebar">
			<h3>Signup</h3>
			<p>Become a member of Jazz Calendar now! <a href="#">Email us</a> to receive frequent notices on upcoming live shows.</p>
		</aside>
		<footer id="contactinfo">
		<p>Jazz Calendar
		<br />123 Fake Street, Sometown, USA | 555-123-4567</p>
		</footer>
	</div>
  </div>
</body>
</html>

Code Explanation:

Open MobileMenus/Demos/jazzslicknav/index.html in a mobile browser and in a code editor to view the code. Also open the associated CSS file, MobileMenus/Demos/jazzslicknav/css/style.css, in a code editor.

We use only two files from the content we downloaded from Slicknav:

  • We link slicknav.css, the Slicknav CSS file, with a link tag in the head of our file.
  • We link jquery.slicknav.min.js, the minified Slicknav JavaScript file, with a script tag in the head of our file, after first including (from a CDN) jQuery.

We call Slicknav from a jQuery ready block, specifying the menu we desire; in our case, it is the unordered list contained within the page's only nav tag. When we do this, Slicknav's JavaScript duplicates our menu and adds some custom CSS classes to hook into its CSS rules.

Last, in our own CSS file style.css, we add rules to hide the mobile menu and show the standard menu for wider browsers/desktops, and to show the mobile menu and hide the standard menu for narrower browsers/mobile devices:

.slicknav_menu {
	display:none;
}

@media screen and (max-width: 520px) {
	.slicknav_menu {
		display:block;
	}
	nav ul {
		display:none;
	}
}

The Slicknav plugin offers some customization options: you can specify the display title (which defaults to "menu"), the symbols to show when the menu is open/closed, and some other features.

One of the more useful options is to specify to which element the mobile menu should be attached. By default, the mobile menu is prepended to the body element; depending on the design and functionality of your page, you might find it better to attach the menu to another element, such as the header:

$('nav ul').slicknav({prependTo: 'header'});

Please see https://github.com/ComputerWolf/SlickNav or more documentation on the SlickNav plugin.

Mobile Menu for Pickup Soccer

Duration: 15 to 25 minutes.

In this exercise, you will add use the Slicknav jQuery plugin to configure a mobile menu for the Pickup Soccer site:

Pickup Soccer Site

  1. Open MobileMenus/Exercises/soccerslicknav.html and MobileMenus/Exercises/css/style.css in a code editor.
  2. Download from https://github.com/ComputerWolf/SlickNav the needed JavaScript and CSS files.
  3. Add Slicknav JavaScript and CSS files to soccerslicknav.html.
  4. Add jQuery to soccerslicknav.html
  5. Add jQuery code to soccerslicknav.html to call Slicknav on the appropriate menu. You may want to attach the menu to an element other than the default body element.
  6. Update style.css to show and hide menus as appropriate for desktop and mobile browsers. You may also want to update the look of the Slicknav menu: try changing the background color or other aspects of the menu.
  7. Test your work in both a desktop and mobile browser.

Solution:

MobileMenus/Solutions/soccerslicknav.html
<!DOCTYPE html>
<html>
<head>
  <title>Soccer Pickup</title>
  <link rel="stylesheet" type="text/css" href="css/reset.css" />
  <link rel="stylesheet" type="text/css" href="css/slicknav.css" />
  <link rel="stylesheet" type="text/css" href="css/style.css" />
  <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
  <script src="js/jquery.slicknav.min.js"></script>
  <script type="text/javascript">
    
    $( document ).ready(function() {
      $('nav ul').slicknav({prependTo: 'header'});
    });

  </script>
  <meta name="viewport" content="initial-scale=1.0, width=device-width" />
</head>

<body>
  <div id="container">
  <header>
  <a href="index.html"><img src="images/logo.png" alt="Soccer Pickup" id="logo" /></a>
  <nav id="mainnav">
    <ul>
    <li><a href="index.html">Home</a></li>
    <li><a href="find-a-game.html">Find a Game</a></li>
    <li><a href="about.html">About</a></li>
    <li><a href="contact.html">Contact</a></li>
    </ul>
  </nav>
  </header>
  <div id="maincontent">
    <h1>Upcoming Games</h1>
        <div class="game">
          <a href="#"><img src="images/tn/ball.jpg" /></a>
          <h3><a href="#">Barry Park</a></h3>
          <p>Sundays, around 2pm; near the back of the largest field</p>
        </div>
        <div class="game">
          <a href="#"><img src="images/tn/feetball.jpg" /></a>
          <h3><a href="#">Lakeside Park</a></h3>
          <p>Sundays, around 2pm; near the back of the largest field</p>
        </div>
        <div class="game">
          <a href="#"><img src="images/tn/goal.jpg" /></a>
          <h3><a href="#">Schiller Elementary School</a></h3>
          <p>Sundays, around 2pm; near the back of the largest field</p>
        </div>
        <div class="game">
          <a href="#"><img src="images/tn/goalframe.jpg" /></a>
          <h3><a href="#">Central High</a></h3>
          <p>Sundays, around 2pm; near the back of the largest field</p>
        </div>
        <div class="game">
          <a href="#"><img src="images/tn/twolegsball.jpg" /></a>
          <h3><a href="#">Adams Park</a></h3>
          <p>Sundays, around 2pm; near the back of the largest field</p>
        </div>
  </div>
  <aside id="sidebar">
    <h3>About Us</h3>
    <p>Soccer Pickup is your source for finding local recreational soccer games for adults. Leagues are great - but sometimes you just want to lace up your boots and find an informal game. Check back often to find a game near you!</p>
  </aside>
  <footer id="footerinfo">
    <p>Soccer Pickup: Your guide to finding a game.</p>
  </footer>
  </div>
</body>
</html>

Code Explanation:

We add references to Slicknav's CSS and JavaScript files, making sure to include jQuery before including the Slicknav JavaScript file.

Inside a script block, we call slicknav on our menu (nav ul).

We pass a parameter to slicknav, telling the plugin we want to attach the mobile menu to the header element, rather than the default body element.

In the CSS file, we set a rule to hide the mobile menu by default and use a set of rules contained in a media query to hide the desktop menu and show the mobile menu for smaller-viewport devices:

.slicknav_menu {
	display:none;
	background-color:#d0b462;
}

@media screen and (max-width: 520px) {
	.slicknav_menu {
		display:block;
	}
	nav ul {
		display:none;
	}
}

We also give .slicknav_menu a background color to match our header.