Web & Software Developer

Pure CSS Responsive Mobile Toggle Menu

This is a CSS-only way to convert your site’s menu into a mobile responsive menu that is wide on desktop screens, and automatically turns into a toggle-menu on small mobile screens.

A toggle-menu is a menu that will be closed until you tap on the menu button. When the menu button is tapped, the menu will open up. When the menu button is tapped again, the menu will close.

Toggle menus are common mobile menus because they provide the best user experience on touch screen phones and other mobile devices.

But this is not common: a pure CSS-only way of having a responsive, mobile toggle menu on your site.

This method uses no JavaScript nor jQuery. This also doesn’t use any icons so there are no heavy icon style sheets to import, nor any font files. With a few lines of CSS, you can have a page-speed optimized, mobile responsive toggle menu.

To begin with, the HTML for your site’s menu should be an unordered list (ul), and it should have a container/wrapper around the ul. In this example, the container around the menu is a nav element:

<nav id="site-navigation" aria-label="Menu">

  <ul id="main-menu">
    <li><a href="#">Home</a></li>
    <li><a href="#">Shop</a></li>
    <li><a href="#">Blog</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Contact</a></li>
  </ul>

</nav>

Your menu container doesn’t have to be a nav element for this work. You can use a div or span, etc. In this example, I’ll refer to the menu container as the nav element, and you can adjust it according to your own menu container.

  1. The first step is to insert the following code just inside the nav element, but before the ul. That would be on line 2 in the code above.

    <label for="toggle-mobile-menu" aria-label="Menu">&#9776;</label>
    <input id="toggle-mobile-menu" type="checkbox" />
    

    (For WordPress users, see below for a way to insert this inside the menu container for wp_nav_menu.)

    After you insert the lines above, the menu now looks like this:

    <nav id="site-navigation" aria-label="Menu">
    
      <label for="toggle-mobile-menu" aria-label="Menu">&#9776;</label>
      <input id="toggle-mobile-menu" type="checkbox" />
    
      <ul id="main-menu">
        <li><a href="#">Home</a></li>
        <li><a href="#">Shop</a></li>
        <li><a href="#">Blog</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Contact</a></li>
      </ul>
    </nav>
    

    That’s all the editing there is for the HTML.

  2. Next, here is the CSS that transforms your regular menu into a mobile-responsive toggle menu. It will only appear as a toggle menu on mobile screens. On desktop screens, it will be a regular, horizontal menu.

    The following CSS works with the sample menu above. However, if you want to modify it to fit an existing site, you’ll want to replace the selectors in the CSS below, to match the selectors for your own menu. For example, replace #site-navigation with the selector for your menu wrapper, and replace #main-menu with the selector for your ul menu.

    #site-navigation {
      display: block;
      background: #000;
      height: 48px;
    }
    
    #site-navigation #main-menu,
    #site-navigation > input {
      display: none;
    }
    
    #site-navigation > label {
      display: block;
      font-size: 36px;
      color: #fff;
      position: absolute;
      right: 20px;
      width: 36px;
      padding: 0;
      cursor: pointer;
      -webkit-touch-callout: none;
      -webkit-user-select: none;
      -khtml-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }
    
    #site-navigation > input:checked + #main-menu {
      display: block;
      clear: both;
      top: 36px;
      position: relative;
      background: #000;
      color: #fff;
    }
    
    #site-navigation ul li {
      display: block;
      padding: 12px 10px;
    }
    
    #site-navigation a {
      text-decoration: none;
      color: #fff;
    }
    
    @media only screen and (min-device-width: 768px) {
      #site-navigation {
        height: auto;
      }
      #site-navigation #main-menu {
        display: block;
      }
      #site-navigation > label {
        display: none
      }
      #site-navigation ul li {
        display: inline-block;
      }
    }
    

    That’s it. The example above is a working, pure CSS, mobile responsive toggle menu. This creates a menu with a black background and white text. You can edit the colors in CSS above.

    For example:

    Change the background color on lines 3 and 34.
    Change the text color on lines 35 and 45.
    Change the color of the “hamburger” menu icon on line 15 (it’s not an actual icon, it’s just an HTML character entity).

For WordPress Users

If you use WordPress, your site’s navigation menu is probably created with the wp_nav_menu function.

It probably looks something like this:

wp_nav_menu( array(
	'theme_location' => 'top',
	'menu_id'        => 'top-menu',
) ); 

By default, wp_nav_menu adds a container around the menu. You can easily insert the code from Step 1 into the menu container by adding the “items_wrap” argument to the wp_nav_menu function.

The “items_wrap” argument would look like this, with the code from Step 1 added:

'items_wrap' => '<label for="toggle-mobile-menu" aria-label="Menu">&#9776;</label><input id="toggle-mobile-menu" type="checkbox" /><ul id="%1$s" class="%2$s">%3$s</ul>' 

So, the call to wp_nav_menu now looks like this:

wp_nav_menu( array(
	'theme_location' => 'top',
	'menu_id'        => 'top-menu',
	'items_wrap'     => '<label for="toggle-mobile-menu" aria-label="Menu">&#9776;</label><input id="toggle-mobile-menu" type="checkbox" /><ul id="%1$s" class="%2$s">%3$s</ul>',
) );

That will take care of adding the necessary HTML from Step 1 to your WordPress site menu.

Now, you can continue with Step 2 and adding the necessary CSS. Using this example of wp_nav_menu, the menu ID selector is top-menu. So, we would change every instance of #main-menu to #top-menu in the CSS code. If you’re using the default Twenty Seventeen theme, the menu container will get the class selector menu-main-container. So, change every instance of #site-navigation to .menu-main-container

By

We've 6 Responses

    • May 4th, 2017 at 6:22 pm

      This is the same code I use on my site. For a live demo, look at this page (or any page on my site) from a mobile phone. 🙂

      avatar
  1. January 20th, 2018 at 10:15 am

    Thanks for a particularly clear explanation of this technique, just what I needed!

    One little note – I added a z-index value after line 35 in your CSS code above so that the toggled menu stayed above a Slippry slider.

    avatar

Questions and Comments are Welcome

Your email address will not be published. All comments will be moderated.

Please wrap code in "code" bracket tags like this:

[code]

YOUR CODE HERE 

[/code]