Skip to content

Mega Menu A11Y

DodaTech 3 min read

title: "Accessible Mega Menu — Complex Dropdown Navigation with Keyboard Support" description: "Learn how to build accessible mega menus with multiple columns, keyboard navigation, focus management, and screen reader announcements for complex hierarchies." weight: 11 date: 2026-06-28 lastmod: 2026-06-28 tags: [accessibility, navigation]


Accessible mega menus provide navigation for complex site structures with multiple columns and categories, using proper ARIA and keyboard support.

## What You'll Learn

How to build mega menus that work with keyboard navigation, manage focus within columns, and communicate structure to screen readers.

## Why It Matters

Mega menus present many navigation options at once. Without accessibility, keyboard users cannot access subcategories, and screen reader users hear an overwhelming list of links.

## Real-World Use

A large e-commerce site has a mega menu with Categories, Brands, and Deals. A keyboard user tabs to "Products" (the top-level trigger), the menu opens, and they use arrow keys and Tab to navigate columns. Escape closes the menu.

## Mega Menu Structure

```html
<nav aria-label="Main">
  <ul>
    <li>
      <button aria-expanded="false" aria-haspopup="true"
              aria-controls="products-menu">
        Products
      </button>
      <div id="products-menu" role="region" aria-label="Products menu" hidden>
        <div role="group" aria-labelledby="cat-heading">
          <h3 id="cat-heading">Categories</h3>
          <ul>
            <li><a href="/laptops">Laptops</a></li>
            <li><a href="/phones">Phones</a></li>
            <li><a href="/accessories">Accessories</a></li>
          </ul>
        </div>
        <div role="group" aria-labelledby="brand-heading">
          <h3 id="brand-heading">Brands</h3>
          <ul>
            <li><a href="/brand-x">Brand X</a></li>
            <li><a href="/brand-y">Brand Y</a></li>
          </ul>
        </div>
      </div>
    </li>
  </ul>
</nav>

JavaScript

const trigger = document.querySelector('[aria-controls="products-menu"]');
const menu = document.getElementById('products-menu');

trigger.addEventListener('click', function() {
  const expanded = this.getAttribute('aria-expanded') === 'true';
  this.setAttribute('aria-expanded', !expanded);
  menu.hidden = expanded;
  if (!expanded) {
    menu.querySelector('a').focus();
  }
});

document.addEventListener('keydown', function(e) {
  if (e.key === 'Escape' && !menu.hidden) {
    menu.hidden = true;
    trigger.setAttribute('aria-expanded', 'false');
    trigger.focus();
  }
});

Common Mistakes

1. Menu opens only on hover

Keyboard users cannot hover. The menu must open on focus or click.

2. No Escape to close

Users must be able to close the mega menu with the Escape key and return focus to the trigger.

3. Focus trapped inside menu

Tab should cycle through links in the menu. Shift+Tab should go back to the trigger.

4. No aria-expanded on trigger

The trigger button must have aria-expanded to communicate open/closed state to screen readers.

Group mega menu links into categories with headings. Each category group needs a label.

Practice Questions

1. What attribute indicates the menu is open? aria-expanded="true" on the trigger button communicates the open state.

2. What key closes the mega menu? Escape closes the menu and returns focus to the trigger button.

3. How do you organize mega menu content for screen readers? Use role=group with aria-labelledby for each category column.

Challenge: Build a mega menu with three category columns and 5-6 links each. Implement keyboard navigation, Escape to close, and focus management.

FAQ

Should mega menu panels be in the DOM order?

Yes. The menu panel should appear immediately after the trigger in DOM order so focus flows naturally.

How do screen readers announce mega menus?

Button: 'Products, collapsed, button.' When expanded: 'Products, expanded, button. Products menu, region. Categories group. Laptops link.'

Can I use a link as a mega menu trigger?

Only if clicking the link navigates somewhere. For toggling a dropdown, use a button.

How do I prevent focus going behind the menu?

When the menu opens, move focus to the first link. When it closes, return focus to the trigger.

Should mega menus close when focus leaves?

Ideally, yes. Use focusout event on the menu container to detect when focus leaves and close the menu.

Mini Project

Create a mega menu for a tech store with columns: Laptops, Phones, Accessories, and Deals. Each column has 4-5 links. Implement full keyboard support.

What's Next

Learn about Hamburger Menu accessibility and how to implement mobile navigation patterns that work for all users.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro