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:
In HTML, the menu button would look something like this:
<button onclick="toggleMenuVisibility()">Menu</button>
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 menuaria-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>
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>
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")
}
}
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>
- 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)
Hi! Nice article. Can I use these attribute on the div tag?