Gordonmac Dot Com

Mostly a web development blog

How to toggle responsive CSS navigation

Posted: February 25th, 2016 | Tags: | Posted in: CSS, jQuery, Tutorials

There are probably hundreds of ways to implement visibility toggling for navigation in responsive states, but this is the way I do it, it’s simple and sane.

See the Pen Basic Responsive Navigation Toggle by Gordon Mackay (@gordonmacdotcom) on CodePen.

The HTML

Nothing exciting about the HTML markup for this. We just create the <nav> container, give it a class of nav--main and then add our unordered list of links:

 
<nav class="nav--main">
	<ul>
		<li><a href="#">Nav Link</a></li>
		<li><a href="#">Nav Link</a></li>
		<li><a href="#">Nav Link</a></li>
		<li><a href="#">Nav Link</a></li>
		<li><a href="#">Nav Link</a></li>
		<li><a href="#">Nav Link</a></li>
	</ul>
</nav>

The CSS

This is where things may start to get a bit confusing. You’ll notice we’re adding styles for a link that isn’t in the HTML markup. The reason for this is simple, we are going to use jQuery to dynamically prepend the HTML for the toggle button (a.btn--menutoggle) to the <nav> container.

There’s another class in the CSS below that doesn’t exist in the above HTML: .nav--responsive. Again we’re going to dynamically generate this class and apply it to the unordered list containing our links.

The reason for dynamically adding this code is simple — the toggle effect relies on jQuery to create the hide/show toggle effect, and by doing things this way we ensure users can still use our navigation if for some reason JavaScript is unavailable when they load the page.

If we didn’t style via the dynamically generated class and instead used display: none directly on .nav--main ul the navigation list would be permanently hidden if JavaScript was unavailable to the user — and that’s not good!

    
a.btn--menutoggle {
	color: #FFF;
	display: block;
	padding: 1em;
	border: 1px solid rgb(90, 114, 131);
	background: rgb(22, 33, 41);
	text-decoration: none;
}

@media (min-width: 40em) {
    a.btn--menutoggle {
        display: none
    }
}


a.btn--menutoggle-active {
	background: rgb(203, 57, 27);
}

.nav--responsive {
	display: none;
}

@media (min-width: 40em) {
    .nav--main .nav--responsive {
        display: block
    }
}

The JavaScript

First, load jQuery (check for the latest version first):

<script type='text/javascript' src='https://code.jquery.com/jquery-2.2.0.min.js'></script>

Now, paste this code into the head of your page.

You can change .nav--main in the snippet below to whatever class or ID you are using for your <nav>.

<script>
jQuery(document).ready(function() {
    jQuery('.nav--main ul').addClass('nav--responsive');
    jQuery('.nav--main').prepend('<a class="btn--menutoggle" href="#">View Menu</a>');
    jQuery('a.btn--menutoggle').click(function(e) {
        e.preventDefault();
        var txt = jQuery(".nav--main ul").is(':visible') ? 'View Menu' : 'Hide Menu';
        jQuery(this).toggleClass("btn--menutoggle-active");
        jQuery(".btn--menutoggle").text(txt);
        jQuery('.nav--responsive').slideToggle();
    });
});
</script>

You can view a demo here.