Home / Components

How do you make a Shopify mega menu accessible?

Published October 10, 2026

Build it for the keyboard first, then add the mouse behavior on top. An accessible mega menu opens on focus as well as hover, moves focus into the panel in a predictable order, closes cleanly on Escape, and never traps anyone inside. Most Shopify mega menus fail at least two of those, usually the hover-only opening and the Escape behavior.

Hover-only is the most common failure

The typical Shopify mega menu opens when the mouse hovers over the top-level item. For a keyboard user, there is no hover, so the panel never opens and the links inside it do not exist. The fix is straightforward: the top-level item must also open the panel on focus, and the panel must stay open while focus moves through it. This is not exotic behavior. It is the documented pattern for disclosure navigation, and it is what every major component library implements by default. Custom theme code is where it gets skipped.

Test this with the keyboard alone, no mouse. Tab to the menu item, and the panel should open. Tab through the panel links in a sensible order, and the panel should stay open until you leave it. Shift-tab back out, and it should close. If any of that fails, the menu is decorative for keyboard users, which means the categories inside it are unreachable. On a store, unreachable categories are unreachable products.

Focus has to go somewhere sensible

When the panel opens, the next question is where focus lands. The worst outcome is that focus stays on the trigger while the panel opens below it, because the screen reader user hears nothing about the new content. The next-worst is that focus jumps to the first link without announcement, leaving the user disoriented about what changed. The right behavior: keep focus on the trigger, but announce the expanded state, and let the user move into the panel with the arrow keys or Tab. The expanded and collapsed states must be exposed programmatically, so the screen reader reports the menu as open.

Inside the panel, the reading order matters as much as the focus order. Mega menus with multiple columns are usually coded as one long list, and the screen reader reads them top to bottom, column by column, which rarely matches the visual layout. Group the panel into labeled sections with headings, so the user hears the structure: the column names become landmarks they can navigate by. A mega menu without internal headings is a wall of links. With headings, it is a map.

Escape must close it, every time

Escape is the universal exit, and mega menus are notorious for ignoring it. The user opens the panel, realizes they are in the wrong section, presses Escape, and nothing happens. Now they have to tab through forty links to get out. The rule is absolute: Escape closes the open panel and returns focus to the trigger. No exceptions, no configuration, no "the theme framework does not support it." If your menu script does not handle Escape, it is unfinished.

Related: clicking outside the panel should close it too, and moving focus entirely out of the navigation should close it. These sound like mouse concerns, but they are keyboard concerns as well, because a panel that stays open while the user moves on creates a confusing layering of content for screen reader users. The menu should behave like a door, not a room: open when you approach, closed when you leave.

The mobile menu is a second menu

Almost every Shopify theme ships a separate mobile navigation, often a slide-in drawer, and it needs the same treatment independently. The drawer must trap focus while open, which is the one place where trapping is correct, and it must return focus to the menu button when closed. The accordion submenus inside the drawer need the same expanded and collapsed announcements as the desktop panel. Teams that fix the desktop mega menu and forget the drawer have fixed the menu for the declining share of their traffic.

Audit both with real tools, not just a checklist. Run a keyboard pass, a screen reader pass, and an automated scan, and do it on the actual theme, not the design file. Mega menus are assembled from theme code, app injections, and custom scripts, and the accessibility of the result is a property of the assembled page. The design was never the problem. The assembly is where menus break.