Ali Jafarian

It’s time to get responsive, folks! Here’s the mobile menu you’ve been waiting for…


Ok, that might have been a little aggressive… but in all seriousness this is a responsive mobile menu tutorial using CSS and jQuery. It offers a clean and simple solution for mobile header navigation. Let us begin!

The HTML

First, we’re going to code a simple header called .responsive-menu which has 3 core elements:

  • Menu Brand (.menu-brand)
  • Menu Nav (.menu-nav)
  • Menu Navicon (.menu-mobile-navicon)

The brand is an element for your logo. The nav is the actual menu of links/items. And the navicon is the icon, often called a “hamburger,” that will toggle the menu in mobile view.

I’ve also thrown in some Font Awesome icons to give the nav some flavor.

<div class="responsive-menu">
	<a href="#" class="menu-brand"><i class="fa fa-align-left"></i> Responsive Menu</a>
	<div class="menu-nav">
		<ul>
			<li><a href="#"><i class="fa fa-home"></i> Home</a></li>
			<li><a href="#"><i class="fa fa-globe"></i> About Us</a></li>
			<li><a href="#"><i class="fa fa-shopping-cart"></i> Products & Services</a></li>
			<li><a href="#"><i class="fa fa-newspaper-o"></i> News & Events</a></li>
			<li><a href="#"><i class="fa fa-envelope-o"></i> Contact Us</a></li>
		</ul>
	</div>
	<!--/.menu-nav-->
	<a href="#" class="menu-mobile-navicon js-mobile-navicon"><span class="bars"></span></a>
</div>
<!--/.responsive-menu-->

On to the CSS!

The CSS

We’re gonna keep the styling lean and clean for this one. The menu itself is fixed so that it stays anchored to the top of the page/viewport. The nav uses some basic list styling.

Our responsive styling takes over at 1024px wide. At this point it hides the nav and displays the navicon. Feel free to adjust this if you want it to happen at a different breakpoint.

I’ve also added in some rgba properties to give a nice transparency effect. The mobile navicon has some very tricky styling… so don’t mess with that unless you know what you’re doing 😉

/* ---------- Responsive Menu ---------- */
.responsive-menu {
	position: fixed;
	top: 0;
	width: 100%;
	height: 70px;
	background: #000;
	z-index: 1000;
	-webkit-transition: .25s;
	-moz-transition: .25s;
	-o-transition: .25s;
	transition: .25s;
}
/* ----- menu brand ----- */
.responsive-menu .menu-brand {
	position: absolute;
	top: 0;
	left: 0;
	padding: 18px 20px;
	font-size: 1.5em;
	font-weight: 700;
	color: #fff;
	text-decoration: none;
	-webkit-transition: .25s;
	-moz-transition: .25s;
	-o-transition: .25s;
	transition: .25s;
	z-index: 1002;
}
.responsive-menu .menu-brand:hover {
	color: #999;
	text-decoration: none;
}
.responsive-menu .menu-brand > i {
	display: inline-block;
	margin-right: 5px;
}
/* ----- menu nav ----- */
.responsive-menu .menu-nav {
	text-align: right;
}
.responsive-menu .menu-nav ul {
	float: right;
	list-style: none;
	font-size: 1em;
	font-weight: 400;
	margin: 0;
}
.responsive-menu .menu-nav ul > li {
	display: inline-block;
	margin: 0;
	vertical-align: top;
}
.responsive-menu .menu-nav ul > li > a {
	display: block;
	height: 70px;
	padding: 25px 30px;
	color: #999;
	line-height: 1.2;
	text-decoration: none;
	-webkit-transition: .25s;
	-moz-transition: .25s;
	-o-transition: .25s;
	transition: .25s;
	vertical-align: top;
}
.responsive-menu .menu-nav ul > li > a:hover {
	background: rgba(255, 255, 255, .15);
	color: #fff;
}
.responsive-menu .menu-nav ul > li > a > i {
	display: inline-block;
	width: 24px;
	margin-right: 5px;
	text-align: center;
	opacity: .5;
}
/* ----- mobile navicon ----- */
.responsive-menu .menu-mobile-navicon {
	display: none;
	position: absolute;
	top: -1px;
	right: 0;
	padding: 18px 15px;
	line-height: 1;
        cursor: pointer;
        user-select: none;
        -webkit-transition: .25s;
	-moz-transition: .25s;
	-o-transition: .25s;
	transition: .25s;
	z-index: 1001;
}
.responsive-menu .menu-mobile-navicon .bars {
	display: inline-block;
    width: 32px;
    height: 2px;
    background: #999;
    transition: 0.3s;
    position: relative;
}
.responsive-menu .menu-mobile-navicon .bars:before,
.responsive-menu .menu-mobile-navicon .bars:after {
	display: inline-block;
    width: 32px;
    height: 2px;
    background: #999;
    border-radius: 0.28571rem;
    -webkit-transition: .25s;
	-moz-transition: .25s;
	-o-transition: .25s;
	transition: .25s;
    position: absolute;
    left: 0;
    content: '';
    -webkit-transform-origin: 0.28571rem center;
    transform-origin: 0.28571rem center;
}
.responsive-menu .menu-mobile-navicon .bars:before {
	top: 10px;
}
.responsive-menu .menu-mobile-navicon .bars:after {
	top: -10px;
}
/* navicon close state */
.responsive-menu .menu-mobile-navicon.navicon-close {
	-webkit-transform: scale3d(0.8,0.8,0.8);
    transform: scale3d(0.8,0.8,0.8);
}
.responsive-menu .menu-mobile-navicon.navicon-close .bars {
	background: transparent;
}
.responsive-menu .menu-mobile-navicon.navicon-close .bars:before,
.responsive-menu .menu-mobile-navicon.navicon-close .bars:after {
    -webkit-transform-origin: 50% 50%;
    transform-origin: 50% 50%;
    top: 2px;
    width: 42px;
}
.responsive-menu .menu-mobile-navicon.navicon-close .bars:before {
    -webkit-transform: rotate3d(0,0,1,45deg);
    transform: rotate3d(0,0,1,45deg);
}
.responsive-menu .menu-mobile-navicon.navicon-close .bars:after {
    -webkit-transform: rotate3d(0,0,1,-45deg);
    transform: rotate3d(0,0,1,-45deg);
}

/* ---------- Media query for tablet/mobile styling ---------- */
@media (max-width: 1024px) {

	.responsive-menu {
		height: 60px;
	}
	.responsive-menu .menu-brand {
		padding: 16px 20px;
		font-size: 1.2em;
	}
	.responsive-menu .menu-mobile-navicon {
		display: inline-block;
	}
	.responsive-menu .menu-nav {
		position: fixed;
		top: 60px;
		right: 0;
		bottom: 0;
		left: 0;
		height: 0;
		padding: 0;
		background: rgba(0, 0, 0, .85);
		overflow: hidden;
		z-index: 1000;
	}
	.mobile-menu-open {
		overflow: hidden;
	}
	.mobile-menu-open .responsive-menu {
		background: #000;
	}
	.mobile-menu-open .responsive-menu .menu-nav {
		height: 100%;
		text-align: left;
	}
	.mobile-menu-open .responsive-menu .menu-nav ul {
		float: none;
		font-size: .9em;
	}
	.mobile-menu-open .responsive-menu .menu-nav ul > li {
		display: block;
		border-left: none;
		border-top: 1px solid rgba(255, 255, 255, .15);
	}
	.mobile-menu-open .responsive-menu .menu-nav ul > li:first-child {
		border-top: 1px solid rgba(255, 255, 255, .5)
	}
	.mobile-menu-open .responsive-menu .menu-nav ul > li > a {
		height: auto;
		padding: 20px;
		color: #fff;
	}

}

The jQuery

And now the JavaScript magic. We’re hooking up a click event to anything with .js-mobile-navicon. This toggles a .mobile-menu-open class to the body, which takes care of all the responsive UI styling. In other words, when that class is present on the body we get all the sweet responsiveness. It also toggles a .navicon-close class on the navicon itself to switch from a hamburger to an x.

$(document).ready(function () {
    // mobile nav
    $('.js-mobile-navicon').on('click', function(e){
    	e.preventDefault();
    	
    	$(this).toggleClass("navicon-close");
    	$('body').toggleClass("mobile-menu-open");
    });
});

And there you have it – a responsive mobile menu using CSS and jQuery. I hope this is useful for you!

Discussion

Leave a Comment

Your email address will not be published. Required fields are marked *