Skip to content

Hamburger Menu

DodaTech 3 min read

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">&#9776;</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

Should I use aria-haspopup on the hamburger?

No. aria-haspopup is for menus that use role=menu. Standard navigation uses aria-expanded and aria-controls.

Does the hamburger menu need role=menu?

No. Standard navigation should not use role=menu. Use a nav with a list of links.

Should the menu overlay have role=dialog?

Only if it acts as a modal overlay that traps focus. Most hamburger menus are not modals.

How do I test the hamburger menu?

Test with keyboard: Tab to hamburger, Enter to open, Tab through links, Escape to close. Test with screen reader: verify aria-expanded changes.

Should hamburger menus be full-screen overlays?

Full-screen overlays are easier to style and prevent background scroll issues. Partial overlays require more attention to focus management.

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