Mobile Menus

September 23, 2016
CSS and SASS Frontend HTML

Mobile menus are seen throughout the internet. The way mobile menus collapse is summarized by one image: the hamburger icon. But going from a fully expanded menu on desktop to a menu that has to be expanded based on user input isn’t as simple as one might think. Sometimes, some CSS & JavaScript is necessary. I’m going to walk you through my method to implement an effective menu collapse.

First, the Markup

Some frameworks and developers encourage you to bloat your HTML by creating a <nav> element with two menus inside, one with id='mobile-nav' and one with no id or id='nav'. I’m certain that’s not necessary and only serves to complicate things.

My method goes a little more like this: Simplify the markup so the menus are the same across platforms. Include the hamburger icon, but hide it above your breakpoint. Clicking the hamburger icon triggers the menuToggle() function, which tests the #menu for it’s class and assigns it the opposite class. In the CSS, define the 'hidden' class to display: none; and the 'active' class to display: inline-block;. Hiding and showing the hamburger icon can be done in CSS, as well. Here’s the markup:

<nav>
  <button onClick='menuToggle()' id='hamburger'>
      <img src='hamburger.png' />
  <button>
  <div id='menu' class='hidden'>
      <a href='#'>Link 1</a>
      <a href='#'>Link 2</a>
      <a href='#'>Link 3</a>
  </div>
</nav>

This menu serves two purposes: easier understanding of the markup and definite consistency between larger screen views and smaller screen views. Encouraging use of different menus opens the door for menu items to be missed or a similar oversight. A menu that shares the same markup between small and large screen views encourages consistency and eases inserting new items or removing old items or refactoring or just updating your site.
The CSS looks something like this:

#hamburger {
  display: none;
}
@media (max-width: /*your breakpoint here*/) {
  #hamburger {
    display: inline-block;
  }
  .active {
    display: block;
  }
  .hidden {
    display: none;
  }
}

And that’s all there is to the CSS, besides styling it the way you want. Now to the easy part: the JavaScript

let menu = document.querySelector('#menu');
function menuToggle() {
  let state = menu.classList.contains('active');
  if (state) {
    menu.classList.remove('active').add('hidden');
  } else {
    menu.classList.remove('hidden').add('active');
  }
}

Again, pretty simple. All of this works together in harmony. A demo of the above with a little extra CSS for styling is found on my CodePen. As you can see, JS can be used to effectively control a nav menu. It can be done quickly and easily, too. If you want your menu to look fantastic all it takes is a little more CSS. You can go even further and add another button in the #menu which calls menuToggle() if you want your menu to overlay the whole page. I’ve used this method lots and lots and find it effective, explainable, and easy to work with.


Update: June 2022

I removed the jQuery in the post. Who uses jQuery? The CodePen hasn’t been changed though, just so that I can look back and laugh at myself.

No Comments...yet

Leave a Reply

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

Previous Post

A Critique on Frameworks

From March 8, 2016

I want to get away from frameworks.

Read This Article