Becoming Responsive, Part 2: Mobile Navigation

Matcha Design - Wednesday, August 26, 2015

There are plenty of challenges in converting a static website into a responsive one which works with browsers both big and small. In Part 1 of this series, we discussed media queries as a tool to make your site more malleable. These handy CSS constructs can go a long way toward your goal of a responsive site.

matcha-design-Becoming-Responsive-P2.jpg

But eventually you'll run up against the challenge of surfing around within your site on a small screen. Traditional headers and navigation bars don't work well on handheld devices. You'd have to shrink them down to the point where they either stack, overlap, or become so small as to be illegible.

In recent years, designers have developed a number of navigation schemes specifically for small screens. These became standardized around a menu button which has affectionately come to be called the "hamburger icon." When a user sees one of these: [img] they know navigation is just a tap away.

There are several approaches to mobile navigation for responsive sites. The most popular is to create two navigation lists in the HTML, and hide one or the other depending on the width of the screen using media queries (there they are again!). This requires a few changes to the HTML so you can generate two navigation lists plus a few other additions. For instance, consider a page set up like this:

<div id="everything">
<nav class="mobile-nav">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/page2">Page 2</a></li>
</ul>
</nav> <!-- close .mobile-nav -->
<div class="main-content">
<header>
<div id="hamburger-icon"><img src="..."></div>
<nav class="regular-nav">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/page2">Page 2</a></li>
</ul>
</nav> <!-- close .regular-nav -->
</header>

... the rest of the content on this page ...

</div> <!-- close .main-content-->
</div> <!-- close #everything -->

When combined with this CSS:

nav.mobile-nav { display: none; }
div#hamburger-icon { display: none; }

... the mobile navigation disappears from the screen forever. That's not quite what we were going for, so let's toss in a media query:

nav.mobile-nav { display: none; }
div#hamburger-icon { display: none; }

@media (max-width: 640px) {
nav.mobile-nav { display: block; }
div#hamburger-icon { display: block; }
nav.regular-nav { display: none; }
}

Now when the screen is 640 pixels wide or smaller, the mobile navigation appears along with the menu icon, and the regular nav bar vanishes. While this does demonstrate the power of @media declarations, it's no more useful than before. Let's fix that:

div#everything { position: relative; width: 100%; overflow: hidden; }
nav.mobile-nav { position: absolute; top: 0; left: -320px; width: 320px; transition: left 0.5s; display: none; }
div.main-content { transition: transform 0.5s; width: 100%; overflow: hidden; }
div#hamburger-icon { display: none; }

@media (max-width: 640px) {
nav.mobile-nav { display: block; }
div#hamburger-icon { display: block; }
nav.regular-nav { display: none; }
}

Whoa! What's all this? In a nutshell, we just positioned the mobile navigation off the left side of the screen. We also added CSS transitions which create smooth one-half-second animations when the mobile-nav or main-content blocks move.

So far so good, except nothing happens when you hit the hamburger icon. That requires a little more CSS plus a tiny bit of Javascript.

div#everything { position: relative; width: 100%; overflow: hidden; }
nav.mobile-nav { position: absolute; top: 0; left: -320px; width: 320px; transition: left 0.5s; display: none; }
div.main-content { transition: transform 0.5s; width: 100%; overflow: hidden; }
div#hamburger-icon { display: none; }
div#everything.active nav.mobile-nav { left: 0; }
div#everything.active div.main-content { transform: translateX(320px); -webkit-transform: translateX(320px); -moz-transform: translateX(320px); }

@media (max-width: 640px) {
nav.mobile-nav { display: block; }
div#hamburger-icon { display: block; }
nav.regular-nav { display: none; }
}

And here's the jQuery snippet which brings it all together:

$('#hamburger-icon').on('click', function() {
$('#everything').toggleClass('active');
});

Do you see what we did here? When you click or tap the menu icon, jQuery toggles the class "active" on the div named "everything," which surrounds all the elements on the page. Meanwhile, in the CSS, we change the position of the mobile-nav and main-content blocks depending on whether or not the "everything" div has the "active" class applied to it. The navigation slides in automatically, pushing the main content aside.

(You may wonder why we used "transform" to move the main-content block instead of "left". Were we to use "left", we'd actually push the edge of the page out to the right, making the page wider than the browser, and the user could accidentally scroll over and hide the navigation. CSS transforms move content around within its own block, which, if "overflow: hidden;" is set, doesn't alter the page layout.)

All right! That was quite the lesson. In our next session, we'll wrap things up with a discussion of scaling oversized elements for responsive sites, so stay tuned.

We at Matcha Design are experts in converting old static sites into clean new responsive ones, as well as creating whole new designs to complement your marketing efforts. Contact us today to see what we can do for you.

About Matcha Design
Matcha Design is a full-service creative agency specializing in web designprintidentitybrandinginterface designvideo productionstill photography and motion design. Using our passion for excellence, multi-cultural background, and award winning practices, we consistently provide high-quality, custom, innovative solutions to meet the diverse marketing needs of our clients. For more information, visit www.MatchaDesign.com.