All components Zyqor Components

Component · mega-menu

Mega menu

A navigation bar with wide panels on desktop and a full-screen accordion sheet on the phone. Hover intent, real buttons, Esc to close, focus that never gets lost.

Vanilla JS2.4 KBKeyboard + EscPhone sheetReduced motion

Use it

Copy the folder mega-menu/ (the .js and .css files) into your project. No build step and no framework.

Behaviour

  • Hover opens after a 90 ms intent delay and closes 220 ms after you leave, so crossing the bar diagonally does not flicker panels.
  • Click and keyboard work without hover: Enter or Space toggles, ArrowDown moves into the panel, Esc closes and returns focus to the button.
  • Phone: full-screen sheet with accordion groups, focus trapped inside, Esc closes, page scroll locked.
  • Panels open with a height animation on grid-template-rows (no fixed heights), links stagger in.
  • prefers-reduced-motion: panels and sheet appear without animation.

Credits

  • Navigation patterns studied on ESR Bespoke by NIGHTJAR (Awwwards SOTD Oct 23 2026, "ESR Navigation" element) and Star Atlas by Hello Monday (SOTY 2021, overlay menu). Disclosure pattern per the WAI-ARIA Authoring Practices. Written from scratch.
  • Accordion physics from Sujon's Drive guide (MA 8.9). Images are Zyqor concept renders. Saltmarsh Ferries is fictional.
<link rel="stylesheet" href="mega-menu.css">
<nav class="mm" data-mega-menu aria-label="Main">
  <div class="mm-bar">
    <a class="mm-logo" href="/">Brand</a>
    <button class="mm-burger" type="button" aria-expanded="false" aria-controls="mm-list">
      <span class="mm-burger-label">Menu</span><i aria-hidden="true"></i></button>
    <ul class="mm-list" id="mm-list">
      <li class="mm-item">
        <button class="mm-trigger" type="button" aria-expanded="false" aria-controls="p1">Routes</button>
        <div class="mm-panel" id="p1"><div class="mm-inner"><div class="mm-grid">...columns...</div></div></div>
      </li>
      <li class="mm-item"><a class="mm-link" href="/about">About</a></li>
    </ul>
  </div>
  <div class="mm-scrim" aria-hidden="true"></div>
</nav>
<script type="module" src="mega-menu.js"></script>
OptionDefaultWhat it does
.mm-triggerA button with aria-controls pointing at its .mm-panel.
.mm-grid3 columns + featurePanel layout on desktop; a single column inside the phone sheet.
breakpoint899pxChange the media queries in the CSS and the mobile() test in the JS together.