Welcome to a tutorial on how to create a responsive navigation menu in HTML and CSS. So you may have stumbled on this responsive thing, and wondering how it is done exactly?
Using a simple collapsing menu as an example, the steps to create a responsive navigation menu are:
- Create the HTML first –
<nav id="res"><a>ITEM</a> <a>ITEM</a></nav>
- Add the CSS styles. In this one, we lay the menu items out horizontally –
#res{ display: flex } #res a { width: 100%; }
- Finally, add styles to cater to mobile devices. In this one, we break the menu items into a vertical list on the small screen –
@media only screen and (max-width: 768px) { #res{ flex-wrap:wrap; } }
Yes, it’s that ridiculously simple. We just create a menu “as usual”, then add responsive support for small screens. Let us walk through a few more common variations of the responsive navigation menu in this guide – Read on!
ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.
REAL QUICK SLIDES
TABLE OF CONTENTS
DOWNLOAD & NOTES
Firstly, here is the download link to the example code as promised.
EXAMPLE CODE DOWNLOAD
Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
QUICK NOTES
If you spot a bug, please feel free to comment below. I try to answer questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.
RESPONSIVE MENUS
All right, let us now get into the common examples of responsive menus in HTML and CSS.
1) COLLAPSING MENU
THE DEMO
THE HTML
<nav id="collapseNav">
<a href="#">Menu A</a>
<a href="#">Menu B</a>
<a href="#">Menu C</a>
<a href="#">Menu D</a>
</nav>
Yes, this is the “full version” of the above snippet in the introduction. Just sandwich <a>
links inside a <nav>
.
THE CSS
/* (A) HORIZONTAL MENU ON BIG SCREEN */
#collapseNav { display: flex; }
#collapseNav a { width: 100%; }
/* (B) SMALL SCREEN - COLLAPSE INTO SINGLE COLUMN */
@media only screen and (max-width: 768px) {
#collapseNav { flex-wrap: wrap; }
}
/* (X) NOT IMPORTANT - COSMETICS */
#collapseNav a {
padding : 10px;
color: #fff;
text-decoration: none;
background: #333;
}
#collapseNav a:hover { background: #8a2222; }
- A – Setting
display: flex
on the navigation menu, andwidth: 100%
on the links will magically turn it into an equally spaced horizontal bar. - B – On the small screens, we set
flex-wrap: wrap
, allowing the links to wrap into new lines. This effectively collapses the horizontal bar into a single column.
2) ICON MENU
THE DEMO
THE HTML
<nav id="iconNav">
<a href="#"><i>℄</i> One</a>
<a href="#"><i>ℋ</i> Two</a>
<a href="#"><i>ℇ</i> Three</a>
<a href="#"><i>℈</i> Four</a>
</nav>
The icon menu maintains a horizontal layout on small screens, but has bigger buttons for fat fingers. In the HTML, we still sandwich <a>
links inside the navigation menu, but we add <i>ICON</i>
tags to add icons to the menu items.
P.S. Check out Toptal for a complete list of the available HTML symbols.
THE CSS
/* (A) HORIZONTAL MENU ON BIG SCREEN */
#iconNav { display: flex; }
#iconNav a { width: 100%; }
/* (B) SMALL SCREEN - LARGE ICON SMALL TEXT */
@media only screen and (max-width: 768px) {
#iconNav a { text-align: center; }
#iconNav i {
display: block;
font-size: 2em;
}
}
/* (X) NOT IMPORTANT - COSMETICS */
#iconNav a {
padding : 10px;
color: #fff;
text-decoration: none;
background: #333;
}
#iconNav a:hover { background: #8a2222; }
- A – Pretty much the same
display: flex
andwidth: 100%
mechanism to equally space the menu items out. - B – On the smaller screens, we simply set a bigger icon and let force the text into a new row –
#iconNav i { display: block; font-size: 2em; }
3) HAMBURGER MENU
THE DEMO
THE HTML
<nav id="hamNav">
<!-- (A) HAMBURGER ICON -->
<label for="hamburger">☰</label>
<input type="checkbox" id="hamburger"/>
<!-- (B) MENU ITEMS -->
<div id="hamItems">
<a href="#">Menu A</a>
<a href="#">Menu B</a>
<a href="#">Menu C</a>
<a href="#">Menu D</a>
</div>
</nav>
The Hamburger Menu is probably one of the most common designs in the world, something like a variant of the collapsing menu. On big screens, it is a “normal” horizontal menu. But it breaks down into a single on small screens, and show/hide toggled by clicking on a menu icon. The HTML should be pretty self-explanatory:
- A – The hamburger menu icon itself. Take note of the checkbox here, we will use this to toggle show/hide on small screens.
- B – Same old “sandwich links in a container”.
THE CSS
/* (A) ON BIG SCREEN */
/* (A1) HORIZONTAL MENU */
#hamItems { display: flex; }
#hamItems a { width: 100%; }
/* (A2) HIDE HAMBURGER ICON */
#hamNav label, #hamburger { display: none; }
/* (B) ON SMALL SCREEN */
@media only screen and (max-width: 768px) {
/* (B1) SHOW HAMBURGER ICON */
#hamNav label { display: inline-block; }
/* (B2) BREAK ITEMS INTO SINGLE COLUMN */
#hamItems { flex-wrap: wrap; }
/* (B3) TOGGLE SHOW/HIDE */
#hamItems { display: none; }
#hamNav input:checked ~ #hamItems { display: flex; }
}
/* (X) NOT IMPORTANT - COSMETICS */
#hamNav label { font-size: 1.5em; }
#hamNav {
padding : 10px;
background: #333;
}
#hamNav, #hamItems a {
color: #fff;
text-decoration: none;
}
#hamItems a { padding: 10px; }
#hamItems a:hover { background: #8a2222; }
- A – On the big screens:
- The same old story yet again,
display: flex
andwidth: 100%
. - Hide the hamburger icon since we don’t need to use it –
#hamNav label, #hamburger { display: none; }
- The same old story yet again,
- B – On the small screens:
- Show the hamburger icon –
#hamNav label { display: inline-block; }
- Collapse the menu into a single column –
#hamItems { flex-wrap: wrap; }
- Hide the menu by default –
#hamItems { display: none; }
- Finally, show the menu when the checkbox is checked (click on menu icon) –
#hamNav input:checked ~ #hamItems { display: flex; }
- Show the hamburger icon –
USEFUL BITS & LINKS
That’s all for this guide, and here is a small section on some extras and links that may be useful to you.
DIVIDE AND CONQUER
The whole responsive mechanism may seem to be intimidating at first. But take it apart piece-by-piece and things will be fine – Deal with the big screen “normally” first, then add styles and changes for the small screens later.
DESKTOP-FIRST VS MOBILE-FIRST
Take note that the above way of “big screen first, add mobile support later” is called the “desktop-first approach”. We can also do it the other way of “deal with small screen first, add desktop support later”. This is called the “mobile-first approach”.
The million-dollar question is, which makes sense and why. There has been quite a bit of debate over that, but my personal conclusion is simple – It depends. If you are expecting most users to be on the mobile, then mobile-first makes sense. If not, desktop-first won’t hurt either.
LINKS & REFERENCES
- CSS Hamburger Menu – Code Boxx
- Using media queries – CSS: Cascading Style Sheets | MDN
INFOGRAPHIC CHEAT SHEET

THE END
Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!