# Examining Responsive Navigation: Toggle Patterns

This post is part of a series called Examining Responsive Navigation Patterns.
Examining Responsive Navigation: Off Canvas Patterns

Welcome to the third in a series on how to develop responsive navigation patterns. This tutorial will walk you through three patterns where navigation is toggled on and off to conserve space at the top of the page.

To recap, in part 1 we developed three patterns where the navigation remained in the header no matter what the screen size. In part 2 we moved the navigation to the footer and developed four more patterns to help visitors access it. In both cases the goal was to minimize the vertical space when the navigation was viewed on smaller screens.

Today we'll walk through three new patterns where the navigation is hidden by default and then revealed when requested. These toggle patterns conserve space by not using navigation until necessary. As with the previous articles these patterns are probably familiar to you through Brad Frost who compiled patterns being used on responsive sites as well as some complex patterns being used.

## The Patterns

The three patterns we'll develop here take one of the footer patterns as their cue. If you remember, the footer anchor pattern placed the navigation at the bottom of the page and used a button at the top to quickly get to it. The downside with that pattern is your visitors jump suddenly from the top of the page to the bottom, possibly disorienting them.

The toggle patterns we'll look at today aim to correct the downside of the footer anchor pattern. Once again we'll start with a button to toggle the menu on and off, but we'll eliminate the jump by opening and closing the navigation in place.

• Toggle — The menu opens by clicking a button and closes by clicking anything off the menu
• Multi-Toggle — Adds an accordion submenu to the basic toggle pattern
• Toggle & Slide — Slides the submenu into place from off screen

As with the previous articles these patterns build on one another. First we'll create the basic toggle. We'll use a similar, though different method for showing and hiding the main menu than we've used previously in this series. Then we'll add in a submenu, first with an accordion pattern and finally by sliding the submenu on and off the screen.

The complete code for all of these patterns is available through the download link above and can also be seen by visiting the demo and viewing the source code. I'll keep the code in this post specific to the menu, submenu, and associated elements.

## The Toggle

The toggle pattern is one of the more popular patterns for handling responsive navigation. By default the menu is hidden and in its place is a single menu button or link. It makes great use of vertical space by following the design principle of progressive disclosure. Only the toggle is initially visible until the menu is requested.

Approach: On the smallest screens we'll create the toggle button and use the checkbox hack to show and hide the menu. We'll style a vertical menu and hide it by default. Then as space allows, we'll use media queries to change the menu so it displays as a horizontal menu of links at the top of the page.

This method is adapted from one presented by Aaron Gustafson.

### Step 1: The HTML

In the first post in this series I introduced the :target pseudo-selector as one way to generate a css only click event. The :target selector matches when the hash in a url and an id on an element are the same. In other words if you have the url domain.com#more then :target will match any element with id="more" added.

Here we'll use another css click event, the checkbox hack. It works by creating a form label connected to a checkbox input. The label will become our menu button and clicking it will check and uncheck the checkbox. We can then use an adjacent sibling combinator to target the menu and show and hide it depending on the :checked state of the input.

The html for this pattern starts with the above mentioned label and checkbox. Through the .btn class we'll style the label to look like a button. You'll notice an empty onclick has been added to the label. It's part of a fix for iOS below version 6, which I'll get to in a bit.

After the label and checkbox is a pretty ordinary unordered list of links with one exception. Notice the last item in the list is another label that targets the checkbox. We'll use it later to hide the menu.

 1   2   3   4  

Before I get to the css let me explain how this is going to work. You'll probably want to check the demo (if you haven't yet) to see what's happening too. You'll want to resize your browser (or whatever device you're using) so it's below 600px. Below this width you should only see the menu button at the top of the page.

Clicking the button will open the menu in an accordion like fashion. Once open you can click anywhere outside the 4 links in the menu to close it. You don't have to click again on the menu button to close the menu. Notice too, that when the menu is closed the button changes color when you hover over it, but the button doesn't change color when you hover over it with the menu open.

What's happening is several elements have been set up to sit at different z-index levels in the stack. When the menu is open it's above the menu button. What you don't see is the close label. This label gets hidden and stretched to cover more than the visible screen. Within the menu it sits behind the other menu items.

So with the menu open the 4 visible links are at the top of the stack. Just below them is the close label that will uncheck the checkbox and turn off the navigation. The label should cover everything on the screen other than the 4 menu items. When you mouse over the menu button with the menu open you aren't really hovering over it. You're hovering over the close label.

Pay attention to the z-indexes set below as you read through the code.

### Step 2: The Default CSS

We'll start by positioning the .btn label in the top right corner of the page. We give it a z-index of 100, though the number itself is arbitrary. Once positioned we'll give the button some padding around it's text, round its corners a little and then set text and background colors.

To give the button a little depth we'll use a gradient and we'll lighten the gradient on hover.

Note: I'm using an older version of the gradient syntax throughout this post as Webkit browsers haven't yet adopted the latest spec. The syntax should work in those browsers that are using the new spec and the gradient isn't required for any of these patterns.

 1 .btn {  2  position: absolute;  3  top: 1.25em;  4  right: 5%;  5  z-index: 100;  6  padding: 0.25em 2%;  7  color: #fff;  8  border-radius: 0.25em;  9  background-color: #5b5756;  10  background-image: -webkit-linear-gradient(top, #6b6766, #5b5756);  11  background-image: -moz-linear-gradient(top, #6b6766, #5b5756);  12  background-image: -ms-linear-gradient(top, #6b6766, #5b5756);  13  background-image: -o-linear-gradient(top, #6b6766, #5b5756);  14  background-image: linear-gradient(top, #6b6766, #5b5756);  15 }  16 17 .btn:hover {  18  background-color: #7b7776;  19  background-image: -webkit-linear-gradient(top, #8b8786, #7b7776);  20  background-image: -moz-linear-gradient(top, #8b8786, #7b7776);  21  background-image: -ms-linear-gradient(top, #8b8786, #7b7776);  22  background-image: -o-linear-gradient(top, #8b8786, #7b7776);  23  background-image: linear-gradient(top, #8b8786, #7b7776);  24 } 

Since we don't need or want to see the checkbox, we'll position it far off the page. Before moving the checkbox off the page, you may want to click the button and also the #close label, just to make sure both actually toggle the checkbox. Once you've proven to yourself that they do, you can move the checkbox off the screen and forget about it.

 1 #toggle {  2  position: absolute;  3  top: -9999px;  4  left: -9999px;  5 } 

With the menu itself we begin by positioning it just below the header and giving it a z-index less than the button. When the menu shows as closed we want the button to be at the top of the stack since it's the only thing that will open the menu.

The menu is hidden by setting the height and line-height of the links to 0 and setting overflow to hidden. Without setting overflow the links do show scrunched up one on top of each other. The accordion effect comes as a result of changing the height and line-height over time and so a transition is added.

 1 #nav {  2  position: absolute;  3  top: 5em;  4  left: 0;  5  z-index: 10;  6  width: 100%;  7  list-style: none;  8  text-align: left;  9 }  10 11 #nav a {  12  height: 0;  13  line-height: 0;  14  display: block;  15  border-bottom-width: 0;  16  background: #444;  17  padding: 0 0 0 5%;  18  overflow: hidden;  19  color:#fff;  20  text-decoration: none;  21 22  -webkit-transition: 0.5s;  23  -moz-transition: 0.5s;  24  -ms-transition: 0.5s;  25  -o-transition: 0.5s;  26  transition: 0.5s;  27 } 

### Step 3: The CSS to Toggle the Menu

Again we're using the checkbox hack to open and close the menu. #toggle is our checkbox and we can use the hack to target an adjacent sibling element, which in our case is the nav element. This allows us to further target anything inside the nav element, which is where we really want to apply our css.

First we'll change the z-index of the menu so it sits above the menu button. A value of 101 works. Then we give the menu a shadow to give it the appearance of sitting on top of the page. The shadow needs to be added here, because it would still show when the menu is closed otherwise.

 1 #toggle:checked ~ nav #nav {  2  z-index: 101;  3  -webkit-box-shadow: 0px 3px 10px 3px #777;  4  -moz-box-shadow: 0px 3px 10px 3px #777;  5  -ms-box-shadow: 0px 3px 10px 3px #777;  6  -o-box-shadow: 0px 3px 10px 3px #777;  7  box-shadow: 0px 3px 10px 3px #777;  8 } 

Next we'll open the menu by setting the height and line-height of the links to 3em. Again the transition set above leads to them opening in an accordion like way. Notice how we've set the links to have a z-index of 1. The entire navigation is still at 101, but inside the navigation links are at a z-index of 1.

This is important as you look down a little further. The #close link is given a z-index of 0 keeping it below the other links. To hide and stretch the #close label, we set it's background to be transparent, and set large negative top and bottom values. The numbers are somewhat arbitrary and may vary depending on your design.

 1 #toggle:checked ~ nav #nav a {  2  line-height: 3em;  3  height: 3em;  4  border-bottom: 1px solid #999;  5  position: relative;  6  z-index: 1;  7   8 #toggle:checked ~ nav #nav a:hover {  9  background: #555;  10 }  11 12 #toggle:checked ~ nav #nav #close {  13  position: relative;  14  z-index: 0;  15 }  16 17 #toggle:checked ~ nav #nav #close label {  18  background: transparent;  19  border-bottom: 0;  20  position: absolute;  21  top: -101em;  22  bottom: -101em;  23  left: 0;  24  right: 0;  25  z-index: 0;  26 } 

At this point the menu should work and you should be able to toggle it on by clicking the menu button and toggle it off by clicking anywhere outside the visible menu.

### Step 4: The CSS in Media Queries

The only thing left to do is change our menu to a horizontal navigation bar once space allows. At 48em we have just enough room. First we'll hide the button by setting its display to none. Next we'll adjust the position of the menu and turn off the shadow. We should do this on both the checked and unchecked states just in case a visitor resizes their browser, by say turning a tablet from portrait to landscape.

 1 @media screen and (min-width: 48em) {  2  .btn {display: none;}  3   4  #toggle:checked ~ nav #nav,  5  #nav {  6  top: 2em;  7  right: 2%;  8  left: 35%;  9  -webkit-box-shadow: 0;  10  -moz-box-shadow: 0;  11  -ms-box-shadow: 0;  12  -o-box-shadow: 0;  13  box-shadow: 0;  14 } 

To display the links horizontally we'll set the list-items to display inline and then float them all to the left. Then we'll reset the height and line-height of the links, reset them to display inline, float them to the right, and give them a little padding. Finally we set the close label to display: none since we don't need it any more.

 1 #nav li {  2  display: inline;  3  float: left;  4 }  5 6 #nav li.current a {  7  color: #7b7776;  8 }  9   10 #nav a {  11  line-height: 1em;  12  height: 1em;  13  display: inline;  14  float: right;  15  background: transparent;  16  padding: 0 1.15em;  17  border-bottom: 0  18 }  19   20 #nav #close {  21  display: none;  22 } 

Above this width there's not a lot that needs to be done other than add a little extra padding between links.

### Step 5:A Fix for iOS and Android

I mentioned at the top we needed something of a fix for iOS less than version 6. We also need a fix for Android version 4.1.2. Neither cares much for the checkbox hack, but both have simple, if unusual, fixes.

We already saw the iOS fix, which was to add the empty onclick event to the label. For Android we add a fake animation to the body element.

 1 body {  2  -webkit-animation: bugfix infinite 1s;  3 }  4 5 @-webkit-keyframes bugfix {  6  from {padding:0;}  7  to {padding:0;}  8 } 

And with that we're done with the basic toggle menu.

### Thoughts

The toggle Pattern is popular because it works well. It conserves vertical space, by using only enough for the toggle button until needed. The majority of css above is to style how the button and menu look when visible. The key to the pattern is in how we toggle the menu on and off.

Here I used the checkbox hack for the toggle, but we could equally use the :target hack we saw in the first post in this series. If you'd like you can also use some Javascript to add and remove a class that turns the menu on and off. We'll see how to use Javascript, specifically jQuery to add and remove classes in the patterns below.

### Examples

The sites below all use the toggle pattern. Notice the different ways each styles the toggle button and the menu itself when it becomes visible.

## The Multi-Toggle

The muti-toggle pattern is the same as the toggle pattern with one addition. It allows for each menu item to contain a submenu. Some sites will use this pattern by keeping the submenus visible when the main menu opens. They simply style them differently so you can tell it's a submenu as opposed to the main menu.That's no fun so we'll hide the submenus until they're requested.

Approach: We'll start by building the same toggle menu described above. One of the menu items (the multi-toggle link) will contain a submenu. This submenu will be hidden initially when the main menu is toggled open. We'll add an indicator to the link and use jQuery to open and close the submenu in an accordion like way.

### Step 1: The HTML

The html is mostly the same as above, with a couple of additions. The obvious addition is the submenu for the Multi-Toggle link. The other additions are the classes given to this link (containts-sub and multi) and the one given to the submenu.

 1   2   3 4  

Since toggling the main menu is exactly the same as above we'll jump directly to the submenu

### Step 2: The Submenu CSS

First let's make sure we're letting visitors know that clicking Mutli-Toggle does something other than take them to a new page. We'll add a downward pointing triangle to indicate this. To keep things simple we'll use the :after pseudo element's content property and add some unicode to display the triangle. Since it looks a little to large initially we'll reduce it's font-size.

 1 .multi:after {  2  content: " \0025Bc";  3  font-size: 0.5em;  4 } 

We'll use the same technique as above (adjusting height and line-height of the links) to have the submenu open in an accordion like way. The selector doesn't look pretty, but we still need to target everything when the checkbox is checked. We'll keep the submenu closed by setting both height and line-height of the links and list items to 0 and once again we'll add a transition. To distinguish the submenu links from the main links we'll give them some extra padding to indent them and also a lighter background color.

 1 #toggle:checked ~ nav #nav .submenu li,  2 #toggle:checked ~ nav #nav .submenu a {  3  height: 0;  4  line-height: 0;  5  -webkit-transition: 0.5s;  6  -moz-transition: 0.5s;  7  -ms-transition: 0.5s;  8  -o-transition: 0.5s;  9  transition: 0.5s;  10 }  11   12 #toggle:checked ~ nav #nav .submenu a {  13  padding-left: 7%;  14  background: #555;  15 } 

For the submenu to display as open it's simply a matter or increasing the height and line-height of link and list item. Notice that the selectors here contain an additional class of open. Our next step is to dynamically add and remove this class with some jQuery.

 1 #toggle:checked ~ nav #nav .submenu.open li,  2 #toggle:checked ~ nav #nav .submenu.open a {  3  height: 3em;  4  line-height: 3em;  5 } 

### Step 3: The jQuery to Open and Close the Submenu

Naturally the first step is to include jQuery itself. You may already be doing this depending on your site, but here's how to include it via Google.

 1  

All we need is a single function to add and remove the class. First we'll grab any link with the .contains-sub class and create a new click function to override the default behavior of the link.

The submenu is a sibling of this link so we find the sibling ul and test to see if it already has the open class. If so we remove the class. If the class isn't present we add it. That's all we need to do. Our css takes care of everything else depending on whether or not the class is present.

 1 $(document).ready(function() {  2 $('a.contains-sub').click(function() {  3  if($(this).siblings('ul').hasClass('open')){  4 $(this).siblings('ul').removeClass('open');  5  } else {  6  $(this).siblings('ul').addClass('open');  7  }  8  return false;  9  });  10 });  ### Step 4: The Media Queries The first set of css we add to the media queries is to hide the toggle button and to change the menu from a vertical list to a horizontal one positioned to the right of the logo. It's exactly the same code we used in the toggle pattern above so I won't repeat it here. One addition though, is to remove the triangle on the :after pseudo content.  1 .multi:after {  2  content: "";  3 }  We do have some css we need to add for the submenu. In the default state we don't want the submenu to show so we'll position it and move it way off the screen. On hover, we'll bring the submenu back by changing the value of left to auto and adjusting the top a little. Note: IE6 only accepts :hover on links. If you need to support IE6 you'll want to use the sfhover class and small Javascript in the Suckerfish drop down system. IE7 does accept :hover on non-link elements provided you use a proper doctype. Most of the remaining code below is purely aesthetic. We assign background colors and borders and set widths and paddings. There are a couple of things to take note of. First we do need to reset the height and line-height of the submenu links. They've only had non zero values when the checkbox is checked and we no longer have that checkbox to check. Second for this demo I turned off the transition on the submenu. There are lots of moving parts to the submenu at this point and having them all move into place didn't look right. Turning the transition off instead of seeking the right combination of what to leave on and what to turn off made more sense.  1 #nav .submenu {  2  position: absolute;  3  left: -999em;  4 }  5 6 #nav li:hover .submenu {  7  left: auto;  8  top: 1.05em;  9  background: #2b2726;  10  max-width: 14em;  11 }  12   13 #nav li:hover .submenu li {  14  border-bottom: 1px solid #999;  15 }  16   17 #nav li:hover .submenu a {  18  height: 3em;  19  line-height: 3em;  20  color: #eae8db;  21  background: #2b2726;  22  padding-right: 1.75em;  23  width: 14em;  24  -webkit-transition: 0;  25  -moz-transition: 0;  26  -ms-transition: 0;  27  -o-transition: 0;  28  transition: 0;  29 }  30 31 #nav li:hover .submenu a:hover {color: #7b7776;}  Once the menu and submenu are in place on wider screens, the remaining media queries exist to make some adjustments in padding and other spacing. ### Thoughts Everything said above about the toggle pattern applies equally to the mutli-toggle pattern. It conserves vertical space until needed. That makes sense as it's simply an extension of the original toggle. Most of the css here is also for aesthetics more than anything else. The key with the submenu is first deciding if it should remain open always or whether or not to open or close it on command. Assuming the latter you'll have to decide how to open and close it. Here we used jQuery to open the submenu in an accordion like way. Our next pattern will offer another way to reveal and hide the submenu. ### Examples While each of the sites below uses a mutl-toggle pattern, notice how each differs in their implementation of the pattern. Keep in mind that you aren't limited to developing this pattern the same way I have here. ## The Toggle & Slide The toggle & slide pattern is the same as the multi-toggle pattern except in how we reveal and hide the submenu. Otherwise it's remarkably similar. Perhaps there's a little more 'wow' to seeing something slide in from off the screen as opposed to opening and closing in place. Approach: Since this pattern is so similar to what we've seen above, we'll jump to the new stuff as quickly as possible. We'll move the submenu to a new menu item and just like above, we'll hide it until someone requests it. However, instead of revealing the submenu with an accordion, we'll slide it in from stage left. ### Step 1: The HTML The html below should look very familiar by now. There are a few differences from above, though. We've moved the submenu to the Toggle & Slide menu item and renamed one of the classes on the submenu from multi to slide. Notice too that the slide and contains-sub classes have been moved to the submenu (ideally contains-sub would have a better name here, since it is the submenu and doesn't contain one). There's also a new link in the submenu. Since we'll be covering the menu item when the submenu slides in, we need a way to slide it back offscreen.  1   2   3 4   ### Step 2: The Submenu CSS Even though the basic idea of what we're doing in this pattern is similar to what we did in the multi-toggle pattern, we need some different css to accomplish it. First we'll modify the indicator we used and go with a right pointing triangle to better indicate the direction the submenu will move.  1 .slide:after {  2  content: " \0025B6";  3  font-size: 0.5em;  4 }  In order to have the menu slide in from off the screen, we'll need to initially position it off screen. Setting absolute positioning with a left value of -100% accomplishes this. As we've done several times we'll add a transition so the submenu appears to move across the screen as its values change.  1 .submenu {  2  position: absolute;  3  left: -100%;  4  top: 0;  5  width: 100%;  6  -webkit-transition: 0.75s;  7  -moz-transition: 0.75s;  8  -ms-transition: 0.75s;  9  -o-transition: 0.75s;  10  transition: 0.75s;  11 }  As with the multi-toggle we'll add an .open class to reveal the submenu and all we need to do to complete the slide is reset the left value to auto. While we're at it we'll change the background color of the submenu links to make it clearer what's going on. And since we're now covering the menu item and need to click the back link, we'll give it a left pointing triangle, again on a pseudo element.  1 .submenu.open {  2  left: 0;  3 }  4 5 .submenu.open a {  6  background: #555;  7 }  8 9 #back:before {  10  content: " \0025C0";  11  font-size: 0.5em;  12 }  ### Step 3: The jQuery to Reveal and Hide the Submenu We need to extend the jQuery function we used to open and close the multi-toggle submenu for the sliding submenu. With the multi-toggle pattern we clicked the same link to open and close the submenu. With the toggle & slide once we open the submenu it covers the link we used to open it. In the html we added a new link "Back" that we'll use to close the submenu. It can't use the same jQuery function though. In the original code we're looking for a sibling of the link that has a class of contains-sub. We don't have that condition with the new Backlink.  1 $(document).ready(function() {  2  $('a.contains-sub').click(function() {  3  if($(this).siblings('ul').hasClass('open')){  4  $(this).siblings('ul').removeClass('open');  5  } else {  6 $(this).siblings('ul').addClass('open');  7  }  8  return false;  9  });  10 11  $('ul.submenu a.contains-sub').click(function() {  12  if($(this).offsetParent('ul').hasClass('open')){  13  $(this).offsetParent('ul').removeClass('open');  14  } else {  15 $(this).offsetParent('ul').addClass('open');  16  }  17  return false;  18  });  19 }); 

Instead we need to grab the parent ul of the link and remove the open class. In all honestly we don't need to include the extra code to for the possibility of adding the class, because the back link will only be visible if the class is already there. We didn't need to include the code for the remove class in the first part either, since it's only when the class isn't there that we'd click the original link.

For this particular example the jQuery could be simplified to:

 1 $(document).ready(function() {  2 $('a.contains-sub').click(function() {  3  $(this).siblings('ul').addClass('open');  4  return false;  5  });  6 7 $('ul.submenu a.contains-sub').click(function() {  8  \$(this).offsetParent('ul').removeClass('open');  9  return false;  10  });  11 }); 

### Step 4: The Media Queries

The code in the media queries for the toggle & slide pattern is mostly the same as what we saw above for the multi-toggle pattern. Once again we hide the toggle, and the arrow on the link, and convert the vertical menu into a horizontal one with a drop down. Instead of showing all the code again, I'll point out a couple of important differences.

First because of the location of the submenu on the last item in the list some negative margin was added to pull it back to the left a little. More importantly the transitions had to be removed in one more place. Since the submenu itself was set up to have a transition to slide across the screen we need to remove that transition. Lastly since we don't need to show the "Back" link anymore will hide it with display: none.

 1 @media screen and (min-width: 48em) {  2  #nav li:hover .slide ~ ul {margin-left: -10%;}  3 4  .submenu {  5  -webkit-transition: 0;  6  -moz-transition: 0;  7  -ms-transition: 0;  8  -o-transition: 0;  9  transition: 0;  10  }  11 12  #nav #back {display: none;}  13 } 

Beyond the above everything else is a minor adjustment in spacing as are all the media queries above this point.

### Thoughts

Like the other patterns, the toggle & slide pattern conserves vertical space until needed. It's very similar to the multi-toggle pattern except we now slide in the submenu from the side instead of opening it like an accordion. This slide is more common on touch devices and so perhaps is the more preferable option.

One extra consideration is where the submenu displays after it slides into place. Here it covered the original link used to slide it into place and so required the addition of a "Back" link and some adjustment to the jQuery in order to slide the submenu off the screen. Another option might have been to have it display slightly lower so it doesn't cover the original link used to open it.

### Examples

While the toggle & slide pattern works well and has a touch of "wow" in the slide transition, it isn't found as often on live sites. The 2 sites below are both making use of this pattern to some degree. Sony uses it similar to how we used it here. Curry's only uses the slide for a menu that's open by default toward the bottom of the page.

## Summary

As in the previous 2 articles these are all patterns on a theme. They all hide the menu by default on small screens and in its place offer a single menu button which can be used to toggle the menu open and closed. We used the checkbox to make the toggle work, though we could have used another css event such as :target like we used in an earlier article.

The mutli-toggle and toggle & slide patterns extend the basic toggle, by providing for a submenu. Both function similarly by using jQuery to override the default click function of a link and add and remove a new class allowing us to style the submenu in two states. They differ in how the css shows, hides, and displays the submenu.

There's one more set of patterns to get to. In the next article we'll look at some off-canvas patterns where either the main navigation or some of the content starts out off the canvas by default and becomes visible only upon request.