Toggle Sidebar B
AppearanceLight & dark mode D

Header Menu

The menu behind a site header's menu button. A sheet that opens under the header instead of over it, follows the finger and closes on a swipe.

Underlay

At desktop width the panel stays put underneath and the page slides away from it, rounding its corners and dimming as it goes. Below that it is an ordinary full width sheet. Open it, then resize the window to see both.

Dark previewReplay previewOpen in new tab
OSMO

Fixed Underlay Navigation

Straight

Flush with the edge and without chrome, like a page of its own. The header stays in view and the button turns into a cross.

Dark previewReplay previewOpen in new tab
Acme

A header that keeps its menu in reach

Open the menu and swipe it away, or press the cross.

Floating

An inset rounded card with a soft shadow, for sites whose pages float on a background.

Dark previewReplay previewOpen in new tab
Acme

A header that keeps its menu in reach

Open the menu and swipe it away, or press the cross.

Glass

Translucent and blurred, so the page stays readable behind the menu. It comes from the left here.

Dark previewReplay previewOpen in new tab
Acme

A header that keeps its menu in reach

Open the menu and swipe it away, or press the cross.

Full

Drops from the top across the whole width, for a menu that takes over the screen.

Dark previewReplay previewOpen in new tab
Acme

A header that keeps its menu in reach

Open the menu and swipe it away, or press the cross.

Anatomy

Import all parts and piece them together.

vue
<script setup>
import {
  HeaderMenu,
  HeaderMenuBurger,
  HeaderMenuClose,
  HeaderMenuPage,
  HeaderMenuPageContent,
  HeaderMenuPanel,
  HeaderMenuReveal,
  HeaderMenuTrigger,
} from "@/components/ui/header-menu";
</script>

<template>
  <HeaderMenu>
    <HeaderMenuTrigger>
      <HeaderMenuBurger />
    </HeaderMenuTrigger>
    <HeaderMenuPanel>
      <HeaderMenuClose />
      <HeaderMenuReveal />
    </HeaderMenuPanel>
    <HeaderMenuPage>
      <HeaderMenuPageContent />
    </HeaderMenuPage>
  </HeaderMenu>
</template>

API Reference

HeaderMenu

PropTypeDefaultDescription
openboolean—Whether the sheet is open. Supports v-model:open.
side"right" | "left" | "top" | "bottom""right"Edge the sheet slides in from. A swipe toward that edge closes it.
variant"straight" | "floating" | "glass" | "full" | "underlay""straight"straight is flush and plain, floating is an inset rounded card, glass is translucent and blurred, full takes the whole width. underlay keeps the panel in place and slides the page away from it at desktop width, and is a full width sheet below that.
namestring—Share this menu's state under a name, so a HeaderMenuPage elsewhere in the layout, not an ancestor, can follow it.
underlayWidthstring"clamp(22rem, 33.333%, 30rem)"Width of the underlay panel, any CSS length. A percentage is of the page.
offsetstring"3.5rem"Height of the header the sheet hangs under, any CSS length. The sheet and its backdrop start below it.
portalTostring | HTMLElement—Keep the sheet inside this element instead of the page. Use it for a menu shown in a frame.
SlotDescription
defaultThe trigger and the panel. Renders no element of its own.

HeaderMenuTrigger

PropTypeDefaultDescription
labelstring"Menu"Accessible name of the button.
textstring—A visible label next to the icon.
barClassstring—Replaces the bar colour, bg-primary by default.

HeaderMenuPanel

PropTypeDefaultDescription
titlestring"Menu"Screen reader title.
descriptionstring"Navigation menu"Screen reader description.
size"sm" | "md" | "lg" | "xl" | "2xl""md" ("sm" when floating)Widest the sheet gets on a screen wider than a phone. On a phone it always takes the whole width, and a sheet from the top or bottom does too.
overlayClassstring—Classes for the backdrop, merged over its defaults. bg-black/80 for a darker one.
bodyClassstring—Classes for the scrolling area that holds the content.

HeaderMenuPage

PropTypeDefaultDescription
namestring—The HeaderMenu to follow when it is not an ancestor, for a page layer in a layout and a menu in the header.
classstring—Wraps the header and the page content. With the underlay variant at desktop width it narrows from the right, rounds its corners and dims while the menu is open.

HeaderMenuPageContent

PropTypeDefaultDescription
classstring—The part of the page that slides sideways by the width of the panel. Leave the header outside it so the logo stays put. It is inert while the menu is open.

HeaderMenuReveal

PropTypeDefaultDescription
asstring"div"A line of the underlay panel. Each one slides in from the right and fades in a beat after the one before it.

HeaderMenuClose

PropTypeDefaultDescription
textstring"Close"Label of the close button inside the panel.

HeaderMenuBurger

PropTypeDefaultDescription
openbooleanfalseMorphs the two bars into a cross.

Accessibility

Keyboard shortcuts and ARIA behavior.

Shortcut Description
Enter + SpaceOpen or close the sheet from the button.
TabMove through the sheet; focus stays inside while it is open.
EscClose the sheet and return focus to the button.
  • Built on the Drawer, so the sheet follows the finger, closes on a swipe toward its edge and on the back button.
  • The button keeps pointer events while the page is locked, so it can close the sheet it opened.
  • Motion is replaced by instant changes under prefers-reduced-motion.