This week I did some research to try to build a hamburger menu that opens a slide-out navigation panel, a common design pattern nowadays. But I wanted to ensure the whole thing was keyboard-friendly and as accessible as possible.
I’m not 100% sure what I’ve come up with is the most accessible solution, but I did consult a number of decent sources on building accessible navigation menus like these. I also did some rudimentary testing using the free NVDA screen reader, to ensure there are no major problems.
You can view the demo embedded below on CodePen:
If you want to try a non-CodePen version to do some accessibility testing on it, you can view it via the button below:
Features of the Hamburger Menu
While I did my best to make this as accessible as possible, I’m more than happy to hear any suggestions. Here are the features of the component:
- It’s keyboard-friendly, so you can use the tab key to navigate around the page including tabbing to the hamburger menu itself
- Uses the UTF-8 symbol referred to as trigram for heaven: ☰ or you can use
- Uses the multiplication sign UTF-8 symbol (× or
×) for the ‘close’ button inside the navigation panel.
- The hamburger menu and the close button are wrapped inside a
- Each button has an
aria-labelthat defines what each one does
- The navigation menu is hidden using
visibility: hiddento ensure it’s not keyboard accessible when it’s closed
- When you open the navigation panel, the page focus goes immediately to the close button; when the panel is closed, focus goes back to the hamburger menu
- The hamburger menu and panel are nested inside a
<nav>element, which seems to be the best option for screen reader users
- The navigation panel can be closed by clicking on the close button, cllicking on the overlay, or by using the
ESCkey on the keyboard
- The hamburger menu uses
aria-expanded, which changes to
<nav>element has its
aria-labelledbyattribute set to the ID of the hamburger button, which helps catalog elements for navigation (credit Birkir for his suggestion in the comments)
Additionally, I’ve added a
tabindex value to the heading and paragraphs elements in the demo so you can see more realistically how to tab around. You wouldn’t normally do this with paragraphs and headings, it’s just for the demo.
The only slightly hacky part of the code is the fact that I’m using
I’m aware that I could use the
transitionend event for this, but I find that event is extremely non-intuitive and it’s just easier to hard-code the timing according to what’s in the CSS. If you can correct this, feel free to fork the CodePen and I’ll add it to the code.
Sources for Building Accessible Navigation
Here are some of the sources I consulted for building this (though I didn’t necessarily follow all the recommendations in these sources):
- Menus & Menu Buttons by Heydon Pickering
- Accessibility for Hamburger Menu by Lilian Lin
- Let’s Focus on Slide-Out Navigation by Alicia Evans
- Invisible Content Just for Screen Reader Users by WebAIM
And once again, here are the demo links:
I’d be happy to hear any suggestions on how to improve the accessibility or anything else in the code to help make this a more complete solution.