Nav Menu Collapse — Container-Driven Navigation

Collapse a horizontal nav menu to a hamburger button when its container narrows below 480px using @container (max-width: 480px) for layout-agnostic navigation.

Use Cases

Detailed Explanation

Navigation That Adapts to Its Slot

Navigation can land in many slots: a wide app header, a narrow side panel, a mobile sheet, or an embedded breadcrumb bar. With container queries, one nav handles all of them.

The Markup

<nav class="nav-host">
  <div class="nav">
    <button class="nav-toggle" aria-label="Open menu">☰</button>
    <ul class="nav-list">
      <li><a href="/">Home</a></li>
      <li><a href="/docs">Docs</a></li>
      <li><a href="/blog">Blog</a></li>
      <li><a href="/contact">Contact</a></li>
    </ul>
  </div>
</nav>

The CSS

.nav-host {
  container-type: inline-size;
  container-name: nav;
}

/* Default: full horizontal menu */
.nav-toggle { display: none; }
.nav-list {
  display: flex;
  gap: 1rem;
}

/* Collapsed: hamburger only */
@container nav (max-width: 480px) {
  .nav-toggle { display: inline-block; }
  .nav-list {
    display: none;
  }
  .nav-list.is-open {
    display: flex;
    flex-direction: column;
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: 100%;
    background: var(--surface);
    padding: 1rem;
  }
}

JS Behavior

Toggle the is-open class on the <ul> from the button's click handler. The CSS handles everything else — no media query checks in JS.

max-width vs min-width

This example uses max-width: 480px because it expresses the design intent ("collapse below this point") more naturally than the inverse. Both forms are valid; pick the one your team finds easier to read.

Accessibility

  • The hamburger button gets aria-expanded="true|false" synced with the open state.
  • Keyboard users can Tab through the menu in both modes.
  • The is-open panel uses role="menu" if you implement arrow-key navigation.

Why Container Queries Beat Viewport Queries

A nav inside a sidebar widget at viewport=1200px is only 250px wide — it should already be hamburger mode. A media query at 480px would keep it horizontal there and break visually.

Use Case

Use this pattern for site headers, embedded navigation widgets, sidebar menus, breadcrumb bars, and any navigation component that needs to work across header, sidebar, and panel placements.

Try It — CSS Container Query Builder

Open full tool