2 Steps Simple Responsive Pure CSS Hamburger Menu

INTRODUCTION
PURE VEGAN CSS MENU

Welcome to a tutorial on how to create a simple responsive pure CSS Hamburger Menu. Yep, there are plenty of other hamburger menus on the Internet, but some of them still require the use of Javascript. So here it is, a menu that is purely CSS driven, not a single line of Javascript. Read on to find out how to build one!

ⓘ 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.

 

 

 

PREAMBLE
SOURCE CODE DOWNLOAD

First, here is the download link to the example source code as promised.

 

SOURCE 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

There is nothing to install, so just download and unzip into a folder. 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.

 

DEMO

Go ahead. Resize the window and see the hamburger menu in action.

 

SECTION A
WHAT IS A HAMBURGER MENU?

For you folks who have stumbled upon this guide, and have totally no idea on why or what people are calling a hamburger menu – You may have noticed the 3 bars symbol () on many websites and mobile applications. Yep, that is the hamburger with a patty sandwiched in between 2 buns.

 

HAMBURGER MENU, NOT JUST THE SYMBOL.

Before some of you guys start to think that a “hamburger menu” is nothing but putting that 3 bars somewhere. Well, there is a little more to it. Typically, the hamburger will not show up on big screens. It is only on the smaller screens that the navigation menu will be collapsed, and the hamburger icon is used to show/hide the menu – That is what we will be building in this tutorial.

 

 

SECTION B
HOW TO BUILD

Building a hamburger menu is actually not that difficult these days with the help of modern CSS…

 

STEP 1) THE HTML

index.html
<!DOCTYPE html>
<html>
  <head>
    <title>Pure CSS Hamburger Menu</title>
    <link href="ham-menu.css" rel="stylesheet">
  </head>
  <body>
    <nav id="hamnav">
      <!-- [THE HAMBURGER] -->
      <label for="hamburger">&#9776;</label>
      <input type="checkbox" id="hamburger"/>
 
      <!-- [MENU ITEMS] -->
      <div id="hamitems">
        <a href="index.html">Home</a>
        <a href="about.html">About</a>
        <a href="tech.html">Tech</a>
        <a href="games.html">Games</a>
        <a href="reviews.html">Reviews</a>
      </div>
    </nav>
  </body>
</html>

The HTML part should be pretty straightforward:

  • First, we need to create the wrapper for the entire navigation menu <nav id="hamnav">.
  • Followed by using a <label for="hamburger"> and <input type="checkbox" id="hamburger"/> as the hamburger button.
  • For people who are new, that &#9776; is the HTML symbol for the “3 lines hamburger icon”.
  • Finally, we just sandwich the actual menu items <a> inside the  <div id="hamitems"> wrapper.
  • No Javascript is required here, as we will be using pure CSS to toggle show/hide the menu items.

 

 

STEP 2) THE CSS

ham-menu.css
/* [ON BIG SCREEN] */
/* Wrapper */
#hamnav {
  width: 100%;
  background: #000;
  /* Optional */
  position: sticky;
  top: 0;
}

/* Hide Hamburger */
#hamnav label, #hamburger { display: none; }

/* Horizontal Menu Items */
#hamitems { display: flex; }
#hamitems a {
  width: 20%; /* 100% / 5 tabs = 20% */
  padding: 10px;
  color: white;
  text-decoration: none;
  text-align: center;
}
#hamitems a:hover {
  background: #401408;
}

/* [ON SMALL SCREENS] */
@media screen and (max-width: 768px){
  /* Show Hamburger Icon */
  #hamnav label { 
    display: inline-block; 
    color: white;
    background: #a02620;
    font-style: normal;
    font-size: 1.2em;
    padding: 10px;
  }

  /* Break down menu items into vertical */
  #hamitems a {
    box-sizing: border-box;
    display: block;
    width: 100%;
    border-top: 1px solid #333;
  }

  /* Toggle Show/Hide Menu */
  #hamitems { display: none; }
  #hamnav input:checked ~ #hamitems { display: block; }
}

/* [DOES NOT MATTER] */
html, body {
  padding: 0;
  margin: 0;
  font-family: arial, sans-serif;
}

HOW IT WORKS – ON BIG SCREENS

The CSS is where all the magic happens. This may seem to be a little complicated, but let’s take it step-by-step. Starting with how to display a “normal menu bar” on the big screens:

  • First, we will hide the hamburger menu icon by attaching display: none to #hamnav label and #hamburger – Since we do not need it on the big screen.
  • Next, we set #hamitems to display: flex.
  • Lastly, set the width of the menu items #hamitems a, and add some cosmetics.

This is actually all the important mechanics on the big screen, and we now have a working horizontal navigation bar.

 

HOW IT WORKS – ON SMALL SCREENS

The above “normal” CSS will display a horizontal menu on big screens. But on the smaller screens, we will need to break the menu down into a vertical one due to screen size constraints, and use the hamburger button to toggle show/hide the menu:

  • As usual, we will use the @media media query to apply a different style for small screens.
  • First, we set a display: inline-block to #hamnav label to show the hamburger icon.
  • Take note that the <input type="checkbox"/> remains hidden.
  • Then, we will break the menu items #hamitems a down to show in a vertical orientation by setting it to display: block and width: 100% instead.
  • Finally, we will hide the menu items #hamitems by default.
  • The magic happens with #hamnav input:checked ~ #hamitems and display: block. This will basically toggle show/hide the menu items as the user checks the hidden checkbox/hamburger button.

 

 

EXTRA
USEFUL BITS

That’s it for the code, and here is a small extra that you may find useful.

 

STICKY MENU BAR

Want the menu bar to be permanently fixed on top of the screen as the user scrolls down on your website? Simply add a position: sticky to the navigation bar, and that should do the magic.

theme.css
#page-nav {
  background: #000;
  position: sticky;
  top: 0;
}

 

 

BIGGER HAMBURGER?

The hamburger icon is an HTML symbol. Yes, changing the size is as easy as setting label[for="hamburger"] { font-size: XX em }.

 

EXTRA
VIDEO TUTORIAL

For you guys who want more, here’s the video tutorial, and shameless self-promotion – Subscribe to the Code Boxx YouTube channel for more!

 

YOUTUBE TUTORIAL

 

INFOGRAPHIC CHEAT SHEET

Pure CSS Hamburger Menu (click to enlarge)

 

CLOSING
WHAT’S NEXT?

Thank you for reading, and we have come to the end of this tutorial. I hope that it has helped you to create a better menu system for your project, and if you have anything to add to this guide, please feel free to comment below. Good luck and happy coding!


21 thoughts on “2 Steps Simple Responsive Pure CSS Hamburger Menu”

  1. This was by a clear mile the clearest and most concise example of a pure css ham nav and it was beautiful – thank you!

  2. Hello and thank you very much. That’s so short and easy to understand and works as is.
    May I please ask, could you maybe do a similar tutorial or maybe please could you share your ideas shortly as an answer .. how to do it, simple like this, but with submenus? there is no need at all for fancy transitions or so, and, the submenu items should be visible until the user ‘clicks’ them away, just to stay like
    menuitem 1
    menuitem 1.1
    menuitem 1.1
    menuitem 2
    .. like this. Maybe kindly please share your ideas? Pure CSS if possible Thank you 🙂

  3. Thanks, nice presentation. I had some issues which I resolved. My issue was one that many people may have, that is converting an existing code base that already has an horizontal list li menu. It took quite a few changes to implement this. Such as not using any of the “Big Screen” code, and redoing the existing css to make it all play nice. All that said, thanks, saved me a ton of time, and a much simpler solution than any other way I saw available.

  4. Actually I was able to solve problem of menu appearing behind other elements by adding
    z-index: 99 !important;
    to my navigation. It works great now. Thanks for this guide!

  5. What is the purpose of using a check box input? This is the second article I’ve read on this subject, both of which call of the check box. And in both cases, using the provided code renders a visible check box on full size screens, and zero responsiveness to the navigation bar.

    1. Really!? How about “actually reading through the entire tutorial and watch the YouTube video”? 🙄 *Hint* The magic happens with #hamnav input:checked ~ #hamitems…

  6. This is amazing! I love it! I made a nice square button with
    nav label {
    /* … */
    border-radius: 5px;
    width: 48px;
    line-height: 48px;
    text-align: center;
    vertical-align: middle;
    }

    One question, though: when the menu is opened, each link visually takes up the full width of the viewport, but most of it does not respond to click/tap. This can be seen in the browser with your example embedded on this page; you have to hover the mouse exactly over the text for the hyperlink to show. Is there any way to make the clickable zone for each navigation link take up the full width, including empty space? Thanks!

  7. After struggling with tons of tricks for hamburger menu (mobile view), i found this one is so simple, easy, and work for my web. No jquery or external script. Thanks.

  8. This was a lot easier to follow than other tutorials I’ve seen. However, mine isn’t working. The hamburger icon is present, but the menu doesn’t drop down once I click on it. Is there a way that we can fix this? I copy and pasted the code, so it should be working. I changed the background color, but that’s it. Also, is there a way that I can resize the hamburger icon. I tried everything with no luck. Thanks for your time and this tutorial.

    1. 1) Resizing the hamburger icon is as easy as adding label[for="hamburger"] { font-size: XX }
      2) The <input type="checkbox" id="hamburger"/> MUST be in the same container as the <ul> menu, since we are targeting them as siblings in CSS – #page-nav input:checked ~ ul { OPEN MENU }

  9. I echo the comment above, been looking at loads of tutorials on this today and this was by far the clearest I have found, really well set out and explained.

    I did find the ☰ code doesn’t display in some older browsers, and as the average age of the people using the website I am managing is probably quite old, I decided to create a little hamburger image instead and it works a treat, even on Chrome v18!

    Thanks!

  10. That has to be the clearest Hamburger menu tutorial I have ever come across – none of the messing about with borders and box shadows to create the lines. Thank you

Leave a Comment

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