How to Build a “Three Line” Drop-down Menu for a Responsive Website in jQuery

3linemain

Our goal is to build a “three line” or “3 line” (☰) menu for a responsive website. We want to do this without adding additional markup to the page. Any additional markup we want to include must be added dynamically. We’re going to use jQuery to help us out.

Initial State

So here is our, initial state.

<!DOCTYPE html>
<html>
<head>
	<title>Responsive 3-Line Menu</title>
	<style type="text/css">
	* {
		margin: 0;
		padding: 0;
	}
	ul {
		width:100%;
	}

	li {
		width:33%;
		float:left;
		border-right: 1px solid #eee;
	}
	li:last-child {
		border-right:none;
	}

	li a {
		display: block;
		width:80%;
		background:#ddd;
		padding:4% 10%;
		font-size:1.35em;
		text-decoration: none;
	}

	@media screen and (max-width: 768px) {
		#menu {
			width:1.4em;
			display: block;
			background:#ddd;
			font-size:1.35em;
			text-align: center;
		}
		#nav.js {
			display: none;
		}
		ul {
			width:100%;
			list-style:none;
		}
		li {
			width:100%;
			border-right:none;
		}
	}

	@media screen and (min-width: 768px) {
		#menu {
			display: none;
		}
	}
	</style>
</head>
<body>
<ul id="nav">
	<li><a href="#">Home</a></li>
	<li><a href="#">About</a></li>
	<li><a href="#">Contact</a></li>
</ul>
</body>
</html>

We have a navigation unordered list with the id of nav. Each menu item is floated left when the browser’s viewport is larger than 768 pixels, any smaller they jump under each other.

Our aim is to hide them when we get to 768 and show a menu (☰). When you tap on the menu it reveals the navigation and once you tap again it hides it.

Getting Started

First we want to hide our navigation unordered list (#nav). In our CSS we’re doing display:none on our #nav.js. We can do this in jQuery in the following way.

$("#nav").addClass("js");

So if JavaScript is enabled it now hides. When we shrink our viewport.

Next we want to add the menu link before our #nav.

$("#nav").addClass("js").before('<div id="menu">☰</div>');

Because we have the CSS already set up to show and hide the ☰ menu we don’t have to do anything here. Next we need to add a click listener to the menu and then toggle the visibility of the #nav element.

$("#menu").click(function(){
	$("#nav").toggle();
});

Finally, if you show and hide the navigation in a small viewport and then expand the viewport again the navigation is always hidden. This is because the toggle method adds a style attribute to the navigation element. To fix this we by removing the style attribute using the removeAttr method. We need to call this when the window resizes and the width is greater than 768 pixels.

$(window).resize(function(){
	if(window.innerWidth > 768) {
		$("#nav").removeAttr("style");
	}
});

And that’s it. In a relatively short amount of code you’ve progressively enhanced a responsive site to have a “three line” menu.

Andrew Chalkley

I'm an alien, I'm a legal alien, I'm an Englishman in Orlando. All of my professional life I've worked with computers online. I'm a polyglot programmer and like using the right tools for the job. In my spare time I enjoy spending time with my young family and when I get chance, sticking opponents in Halo 4. You can find me in most places @chalkers.

Comments

  • nobj

    How to dowload full example ? Who do can share ? Mail: nhannn@bkc.vn

  • Jordan

    any clever way to have this thing animate?

  • M. McKendry

    Can you put up an example to download?

  • MichMcK

    Could you make a full example WITH the jQuery so that I can copy and paste it? I’m getting the nav but it’s not collapsing. Thanks!!

  • Me me me!

    I agree Aweosme :D Definitely will use this!

  • Richard Martin

    @chalkers:disqus

    I was testing your demo and I love it, its so simple its unreal.

    I have noticed a bug however it probably is not going to affect anyone because you don’t often resize the viewport

    reproduce:
    1) scale browser window from desktop size to < 768px

    2) open navigation or search
    3) scale window back to desktop size

    the menu icons appear out of line and the search icon does not return to original size.

    Otherwise a perfect solution!
    Thanks.

    Rich.

  • magic

    how to add an animation to the movement?

  • Harjeet Singh

    Please add the link to demo of the menu.
    Team S plus H

  • chris

    thnaks for this tutorial

  • MichMcK

    PA-LEEEEEZE put a downloadable example of this html, CSS and jQuery. I’m having trouble understanding where/how to do the script.

    Thanks

  • tabby

    would love to see the full code, don’t know enough about implementing jquery to get this to work :/