How to build a really simple responsive menu

13th December 2016

Language(s): HTML/CSS, JavaScript | Theme(s): Development

All you’ll need in this tutorial is a bit of knowledges in HTML, a good comprehension of the mediaqueries in CSS and understand how is working the JS function that we gonna use, to make our responsive menu.

First of all, to make a simple responsive menu, we need to make a HTML skeleton as clear as possible with some lorem ipsum to simulate the content.

Step 1 – HTML skeleton


<!doctype html>
<html lang="fr">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>Simple responsive menu | by owltools.io</title>
	</head>
	<body>
		<nav class="navigation">
			<div class="nav-logo">Your Logo</div>
			<ul class="nav-menu">
				<li><a href="">Link 1</a></li>
				<li><a href="">Link 2</a></li>
				<li><a href="">Link 3</a></li>
				<li><a href="">Link 4</a></li>
			</ul>
			<div class="nav-toggle">
				<span class="icon-bar"></span>
		        <span class="icon-bar"></span>
		        <span class="icon-bar"></span>
			</div>
		</nav>
		<div class="nav-overlay"></div>
		<div class="site-container">
			<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque aliquam purus vel velit gravida, ut molestie velit imperdiet. Morbi pharetra leo nec posuere faucibus. Suspendisse nec ante at est consequat fermentum. Duis vel neque turpis. Nullam venenatis ex at elit mollis mattis. Donec aliquet accumsan maximus. Proin cursus tortor eget ligula semper, et ultricies odio iaculis. Sed arcu erat, luctus eleifend lacinia vel, ornare sed risus.</p>

			<p>Duis eget molestie ligula. Suspendisse bibendum imperdiet sem, vel pellentesque dolor mattis eu. Mauris ut mauris ac mauris finibus aliquam. Nulla facilisi. Sed ut elementum risus. Etiam quis porttitor mauris, sed maximus nisl. Morbi ultricies convallis pulvinar. Nam vulputate turpis nec sem molestie, eu feugiat elit ultricies. Donec vel suscipit ante. Aenean elit ligula, suscipit et mauris vel, dignissim egestas felis.</p>
			
			<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque aliquam purus vel velit gravida, ut molestie velit imperdiet. Morbi pharetra leo nec posuere faucibus. Suspendisse nec ante at est consequat fermentum. Duis vel neque turpis. Nullam venenatis ex at elit mollis mattis. Donec aliquet accumsan maximus. Proin cursus tortor eget ligula semper, et ultricies odio iaculis. Sed arcu erat, luctus eleifend lacinia vel, ornare sed risus.</p>
		</div>
	</body>
</html>

Step 2 – Import CSS/JS and external links

In step 2 we import all the files we need to stylize and animate our page.


//Import this in the HTML head
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,700" rel="stylesheet"> 
<link rel="stylesheet" href="css/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

//Import the JS file before the body closure
<script src="js/main.js"></script>

Description :

  • Google Fonts : We import the Roboto Google font just to make the tutorial sweeter.
  • The Stylesheet : Size is our stylesheet, where we gonna stylize our HTML tags. Put it where ever you want, but it is always better to tide your files, then create a sub folder named “/css”.
  • jQuery 3.1.1 : We import the jQuery library in our site to make the menu working in the next steps.

The JS

For this step, we let the “main.js” file empty.

The CSS

Before our CSS, we’ll use a small reset to reduce browser inconsistencies. In this case, we use the CSS RESET made by meyerweb.com (click the link for more infos).

Let’s see how we layout the navigation. First we specify the colors (make things easier when you develop websites), the dimensions of each element, their position (relative, fixed, absolute), the way they float.

In our case, we gonna build a really simple menu, with “your logo” floating on the left, the menu list floating next to it and the navigation toggle (visible for now) sticking to the top right corner.


/* GENERAL */

body{
	background-color:#f3f3f3;
	min-height:100vh;
	font-family: 'Roboto', sans-serif;
}

/* NAV */

nav.navigation{
	position:relative;
	height:50px;
	background-color:#3c3c3c;
	z-index:2;
}
.nav-logo{
	float:left;
	height:50px;
	line-height:50px;
	padding:0 20px;
	background-color:#11999e;
	color:#ffffff;
	font-weight:700;
	text-transform:uppercase;
}
ul.nav-menu, ul.nav-menu li, ul.nav-menu li a{
	float:left;
}
ul.nav-menu{
	padding-left:10px;
}
ul.nav-menu li a{
	height:50px;
	line-height:50px;
	padding:0 10px;
	color:#ffffff;
	text-decoration:none;
}
ul.nav-menu li a:hover{
	color:#6decb9;
}
.nav-toggle{
	position:absolute;
	top:0;
	right:0;
	width:50px;
	height:50px;
	background-color:#11999e;
	cursor:pointer;
}
span.icon-bar{
	position:absolute;
	right:12px;
	display:block;
	width:26px;
	height:2px;
	background-color:#ffffff;
}
.icon-bar:nth-child(1){
  top:17px;
}
.icon-bar:nth-child(2){
  top:24px;
}
.icon-bar:nth-child(3){
  top:31px;
}
.nav-overlay{
	position:absolute;
	top:0;
	right:0;
	bottom:0;
	left:0;
	background-color:rgba(0,0,0,0.5);
	z-index:1;
	opacity:0;
	visibility:hidden;
}
.nav-overlay.active{
	opacity:1;
	visibility:visible;
}

/* SITE CONTAINER */

.site-container{
	width:80%;
	margin:5%;
	padding:5%;
	background-color: #ffffff;
	font-size:16px;
	font-weight:300;
	line-height:20px;
}
.site-container p{
	margin:10px 0;
}

Step 3 – The toggleClass JS function and the first lines of mediaqueries

In step 3 we start to make this menu live.

The toggleClass function

Add or remove one or more classes from each element in the set of matched elements, depending on either the class’s presence or the value of the state argument (source: jQuery.com).

This function allows us to put and remove a class from an element what ever if this one is already present or not. We gonna use this function to make the menu “active” or “inactive”.


//menu toggle
(function($){
    $('.nav-toggle').click(function(e){
        e.preventDefault();
        $('.nav-menu').toggleClass('active');
    })
})(jQuery);

The mediaqueries

Before to go into the mediaqueries, don’t forget to hide the “.nav-toggle” element in your CSS as we don’t want it to be displayed on big screens.


.nav-toggle{
	display:none;
}

Then after this, the goal is to stylize the elements for small screens (in our case screens<767px). We use this mediaquerie:


@media screen and (max-width:767px){
}

And the second thing to do, is to stylize the active elements like the “.nav-menu” element. Here is the full mediaquerie CSS code:


@media screen and (max-width:767px){
	ul.nav-menu{
		position:absolute;
		top:50px;
		width:100%;
		height:0;
		padding:0;
		overflow:hidden;
	}
	ul.nav-menu.active{
		height:auto;
	}
	ul.nav-menu li{
		width:100%;
	}
	ul.nav-menu li a{
		width:100%;
		padding:0;
		text-align:center;
		background-color:#2c2c2c;
	}
	ul.nav-menu li a:hover{
		background-color:#1c1c1c;
	}
	.nav-toggle{
		display:block;
	}
}

Explainations

  • We set the default height of the menu to 0 and we hide the overflow to make it disappear. Then we set the height to auto when the element gets the “.active” Class in order to make the menu collapsible.
  • We change the dimensions of the “.nav-menu”  elements (li, li a) in order to make them fitting well with the new width (100%).
  • We set the “.nav-toggle” CSS attribute “display” to “block” to make it visible for the users on small screens (under 767px).

Step 4 – Additional features, animations and overlay

Here we are, we just got a beautifull and minimalist responsive menu, just with simple HTML/CSS and a snippet of JavaScript !
But to go further, you could add some animation, or an overlay to hide the content while openning the menu.

Simple animations with CSS

The trick is to add a “transition-duration” to the elements that you want to animate!


*{
	-webkit-transition-duration: 0.3s;
	-o-transition-duration: 0.3s;
	transition-duration: 0.3s;
}

Animate the “.nav-toggle” icon-bars

The idea is to create an animation between the default and active mode of the button. In order to make this, we put the exact transition-duration as the previous example on the “span.icon-bar” element in the CSS.


span.icon-bar{
	-webkit-transition-duration: 0.3s;
	-o-transition-duration: 0.3s;
	transition-duration: 0.3s;
}

And also add a toggleClass function for the “.nav-toggle” element in the “main.js” file.


//menu toggle
(function($){
    $('.nav-toggle').click(function(e){
        e.preventDefault();
        $('.nav-toggle').toggleClass('active');
        $('.nav-menu').toggleClass('active');
    })
})(jQuery);

Then after this we just have to stylise the “span.icon-bar.active” element in the CSS.


/* ICON BARS ANIMATION */

.nav-toggle.active .icon-bar:nth-child(1){
	top:24px;
	-webkit-transform: rotate(45deg);
	-moz-transform: rotate(45deg);
	transform: rotate(45deg);
}
.nav-toggle.active .icon-bar:nth-child(2){
	width:0;
}
.nav-toggle.active .icon-bar:nth-child(3){
	top:24px;
	-webkit-transform: rotate(-45deg);
	-moz-transform: rotate(-45deg);
	transform: rotate(-45deg);
}

The overlay

The goal of the overlay is to make the rest of the site darker to make the users more focus on the menu. In the HTML, add a “.site-overlay” element.


<div class="nav-overlay"></div>

Then in the CSS and JS specify:


nav.navigation{
	z-index:2;
}
.nav-overlay{
	position:absolute;
	top:0;
	right:0;
	bottom:0;
	left:0;
	background-color:rgba(0,0,0,0.5);
	z-index:1;
	opacity:0;
	visibility:hidden;
	-webkit-transition-duration: 0.3s;
	-o-transition-duration: 0.3s;
	transition-duration: 0.3s;
}
.nav-overlay.active{
	opacity:1;
	visibility:visible;
}
@media screen and (min-width:768px){
	.nav-overlay.active{
		visibility:hidden;
		opacity:0;
	}
}


//menu toggle
(function($){
    $('.nav-toggle').click(function(e){
        e.preventDefault();
        $('.nav-toggle').toggleClass('active');
        $('.nav-menu').toggleClass('active');
        $('.nav-overlay').toggleClass('active');
    })
})(jQuery);

Explainations

  • We set the “z-index” of the nav and the overlay respectively to “2” and “1” to put the overlay behind the menu (by default everything is set to 0, then the browser decides it slef where to put the elements and you could see your overlay over the menu and we don’t want that).
  • We add a mediaquerie for screens bigger than 768px, because when your menu is open and you decide to resize your window, the “.nav-overlay.active” is still visible while we return in “Desktop” mode. Then with this mediaquerie we delete the overlay when screens are bigger than 768px whatever the situation.
  • We add a toggleClass functions to allow the “active” mode of the overlay.

Make the menu closing by clicking the overlay

The last thing you could to to incrase the experience is to make the overlay clickable to allow the users to exit the menu by clicking in the “void”. In order to make this, you just need to duplicate the click event in the “main.js” file and replace the object “.nav-toggle” by “.nav-overlay”.


//menu toggle
(function($){
    $('.nav-toggle').click(function(e){
        e.preventDefault();
        $('.nav-toggle').toggleClass('active');
        $('.nav-menu').toggleClass('active');
        $('.nav-overlay').toggleClass('active');
    })
    $('.nav-overlay').click(function(e){
        e.preventDefault();
        $('.nav-toggle').toggleClass('active');
        $('.nav-menu').toggleClass('active');
        $('.nav-overlay').toggleClass('active');
    })
})(jQuery);

About the author

Bastien Delmare - Freelance Digital Designer
http://bastiendelmare.com

I'm a digital mercenary. During the last years I've been walking around the digital area, still learning everyday, this domain is an infinite source of inspiration who makes my days. Today as a freelancer I'm trying to take every project as a challenge because new knowledges, new technologies or innovative ideas are often required!