Hamburger Menu
title: "Hamburger Menu — Accessible Mobile Navigation Patterns" description: "Learn how to build accessible hamburger menus with aria-expanded, focus management, body scroll lock, and keyboard navigation for mobile navigation." weight: 12 date: 2026-06-28 lastmod: 2026-06-28 tags: [accessibility, navigation]
Accessible hamburger menus provide a compact mobile navigation pattern with proper button semantics, aria-expanded state, and focus management when opening and closing.
## What You'll Learn
How to implement an accessible hamburger menu that works with screen readers, keyboard navigation, and touch devices.
## Why It Matters
The hamburger icon has no inherent meaning. Without proper ARIA, screen reader users hear "button" without knowing it controls navigation.
## Real-World Use
A user on a mobile device taps the hamburger icon. The navigation panel slides in. A screen reader announces "Open navigation menu, button, expanded." The user tabs through the navigation links.
## Hamburger Implementation
```html
<header>
<nav aria-label="Main">
<button aria-expanded="false" aria-controls="nav-menu"
aria-label="Open navigation menu">
<span aria-hidden="true">☰</span>
</button>
<ul id="nav-menu" hidden>
<li><a href="/">Home</a></li>
<li><a href="/products">Products</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
</header>
JavaScript
const hamburger = document.querySelector('[aria-controls="nav-menu"]');
const menu = document.getElementById('nav-menu');
hamburger.addEventListener('click', function() {
const expanded = this.getAttribute('aria-expanded') === 'true';
this.setAttribute('aria-expanded', !expanded);
menu.hidden = expanded;
this.setAttribute('aria-label',
expanded ? 'Open navigation menu' : 'Close navigation menu');
if (!expanded) {
menu.querySelector('a').focus();
} else {
this.focus();
}
});
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && !menu.hidden) {
menu.hidden = true;
hamburger.setAttribute('aria-expanded', 'false');
hamburger.setAttribute('aria-label', 'Open navigation menu');
hamburger.focus();
}
});
Body Scroll Lock
function toggleBodyScroll(lock) {
if (lock) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = '';
}
}
Common Mistakes
1. Using a div or span as the hamburger button
Use a button element so it is keyboard-focusable and has implicit button semantics.
2. No aria-label on the hamburger
"Open navigation menu" is clearer than the default button announcement.
3. Menu not hidden from screen readers when closed
Use the hidden attribute on the menu. When hidden, links inside are not focusable.
4. Focus not managed when menu opens
Focus should move to the first menu item when opened and back to the hamburger when closed.
5. No Escape key handler
Users must be able to close the menu with Escape and have focus return to the hamburger.
Practice Questions
1. What HTML element should the hamburger icon be? A button element for proper keyboard focus and implicit role semantics.
2. What happens to focus when the menu closes? Focus returns to the hamburger button so the user can continue navigating from where they started.
3. What aria attribute changes when the menu opens? aria-expanded changes from "false" to "true" and aria-label changes to "Close navigation menu."
Challenge: Build a responsive hamburger menu. On mobile (below 768px), show hamburger. On desktop, show full navigation. Implement full keyboard and screen reader support.
FAQ
Mini Project
Create a responsive navigation that shows a hamburger menu on mobile (below 768px) and full horizontal navigation on desktop. Include focus management and screen reader support.
What's Next
Learn how to indicate Current Page in Navigation using aria-current to help users understand their location in the site.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro