DEV Community

Cover image for The problem with the hamburger menu and how to fix it
Savvas Stephanides
Savvas Stephanides

Posted on • Edited on

The problem with the hamburger menu and how to fix it

About

Do you have a hamburger menu on your website? You probably do. And why wouldn’t you? It helps unclutter a busy website on mobile.

However there’s a problem. It’s not accessible if you haven’t actually put the time and effort to do it so.

The good news is that this can be fixed. Let’s see how.

The situation

Firstly, it’s safe to assume that your hamburger menu looks and acts something like this:

GIF animation of menu expanding and collapsing at the click of a button

In HTML, the menu button would look something like this:

<button onclick="toggleMenuVisibility()">Menu</button>
Enter fullscreen mode Exit fullscreen mode

How you implement toggleMenuVisibility() is up to you, but we will update it at some point.

The problem

The problem now is that unless you specify as such, there’s no way for a screen reader to know if this is a button which expands a menu.

The screen reader will read the button as follows:

Menu, button

This means that blind users, only know that this is a button called Menu and is not clear that it does what it does (i.e. expanding a menu).

This is where ARIA attributes come in.

The solution

For your menu button, you’ll need two attributes:

  • aria-haspopup to announce to the screen reader that or button will show a menu

  • aria-expanded to signify the status of our menu, expanded or collapsed

Firstly, let’s add aria-haspopup to our button:

<button onclick="toggleMenuVisibility()" aria-haspopup="true">Menu</button>
Enter fullscreen mode Exit fullscreen mode

Next we’ll add aria-expanded. We’ll default this to false since initially, the menu is hidden.

<button onclick="toggleMenuVisibility()" aria-haspopup="true" aria-expanded="false">Menu</button>
Enter fullscreen mode Exit fullscreen mode

After adding these two attributes, the screen reader will read the Menu button as follows:

Menu, menu pop-up, collapsed, button

This now gives a clear indication to screen reader users that this button will expand something when clicked. Much more informative!

Finally, we need to update the status of aria-expanded every time the user taps the hamburger menu button so that it’s set to true when the menu is open, and false when the menu is closed. For this, we'll need to update our toggleMenuVisibility() function to set our attribute:

var menuElement = document.querySelector("#menu")
+ var menuButtonElement = document.querySelector("#menu-button")

function toggleMenuVisibility(){
  var currentStatus = menuElement.getAttribute("status")

  if(currentStatus === "visible"){
    menuElement.setAttribute("status", "hidden")
+    menuButtonElement.setAttribute("aria-expanded", "false")
  }
  else{
    menuElement.setAttribute("status", "visible")
+    menuButtonElement.setAttribute("aria-expanded", "true")
  }
}
Enter fullscreen mode Exit fullscreen mode

If you now open your page with a screen reader and tap on the Menu button to open the menu, the screen reader will say something along the lines of:

Menu, menu pop-up, expanded, button

If you tap the Menu button again, once again it'll read:

Menu, menu pop-up, collapsed, button

Perfect! Exactly what we need the screen reader to say to keep all our users informed.

And you should be set! Your hamburger menu should now be accessible!

Further considerations

1. Provide alternative labelling for hamburger icons

If you're using a hamburger icon from FontAwesome, Bootstrap or an image, make sure you use aria-label and aria-hidden attributes to provide alternative labels for screen readers:

<a href="#" aria-label="Collapse or expand the menu">
  <i class="fas fa-bars" aria-hidden="true"></i>
</a>
Enter fullscreen mode Exit fullscreen mode

2. Make sure the menu has the focus after expanding it

Keyboard and screen reader users want to access the menu immediately after tapping/clicking on the Menu button. Make sure your menu has the focus immediately after expanding it.

That’s too much work! What’s the point?

I'm going to end this article the same way I ended my previous article on inaccessible typewriter effect. You have an obligation as a human first, and as a developer second, to be inclusive in your work, even your personal portfolio. Be inclusive. Be human.

How about you?

Have you taken steps to make your menu more accessible? What are they and what difficulties have you faced? Let me know in the comments or on Twitter!

Top comments (1)

Collapse
 
yagneshp profile image
Yagnesh

Hi! Nice article. Can I use these attribute on the div tag?