Skip to content
The Membrane Palette
Navigationbeta

Menu

A list of actions in a native popover — opened by a popovertarget button, light-dismissed by the browser, arrow-key navigable with membrane.js.

Examples

Actions menu

HTML for “Actions menu”
<button class="mp-button" type="button" data-variant="secondary" popovertarget="menu-workshop" aria-haspopup="menu" aria-expanded="false">Workshop actions</button>
<div class="mp-menu" id="menu-workshop" popover role="menu" aria-label="Workshop actions">
  <p class="mp-menu__label" role="presentation">Edit</p>
  <button class="mp-menu__item" type="button" role="menuitem">
    <svg class="mp-icon" viewBox="0 0 24 24" aria-hidden="true"><rect x="8" y="8" width="14" height="14" rx="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>
    Duplicate
  </button>
  <button class="mp-menu__item" type="button" role="menuitem">Export syllabus</button>
  <button class="mp-menu__item" type="button" role="menuitem" aria-disabled="true">Move to cohort (none open)</button>
  <hr class="mp-menu__separator">
  <button class="mp-menu__item" type="button" role="menuitem" data-tone="danger">Archive workshop</button>
</div>

Guidance

For secondary actions that don't deserve permanent space: "Duplicate", "Export", "Archive". Built on the native popover attribute, so the browser handles opening, top-layer stacking, Escape and click-outside. components/membrane.js adds the WAI-ARIA menu keyboard pattern (↑/↓, Home/End, focus on open, return focus on close), keeps aria-expanded in sync and positions the menu in browsers without CSS anchor positioning.

When not to use

  • Navigation between pages → links in a Navbar.
  • Choosing a value for a form → a <select> (Input).

Accessibility

  • The trigger has popovertarget, aria-haspopup="menu" and aria-expanded (kept in sync by membrane.js).
  • The popover has role="menu" and an aria-label; items are <button role="menuitem">. Separators and group labels are presentational.
  • Keyboard (with membrane.js): opening focuses the first item; ↑/↓ move, Home/End jump, Escape closes and returns focus to the trigger; choosing an item closes the menu.
  • Destructive items use data-tone="danger" and a clear verb — color is never the only signal. Follow them with a confirmation Dialog.

Manual screen-reader and usability checks have not been recorded for this inventory. See the accessibility evidence for automated coverage, remaining checks and the result-recording protocol.

API

Menu classes
ClassKind
.mp-menuroot
.mp-menu__itempart of .mp-menu
.mp-menu__separatorpart of .mp-menu
.mp-menu__labelpart of .mp-menu
Menu attributes
AttributeValues
data-tonedanger

States styled: :disabled :focus-visible :hover :popover-open [aria-disabled="true"]. Set the native attribute or ARIA state; there are no state classes.

Menu component tokens
TokenDefaultLight · dark
--mp-menu-bgvar(--color-bg-elevated)#FAF6EE · #27272D
--mp-menu-fgvar(--color-text-primary)#2A2622 · #F0EBE1
--mp-menu-item-bg-hovervar(--color-bg-hover)rgba(42, 38, 34, 0.06) · rgba(240, 235, 225, 0.06)
--mp-menu-dangervar(--color-error-text)#A53434 · #F07C78
--mp-menu-labelvar(--color-text-tertiary)#6E685F · #938D83

Design tokens consumed: --border-default --border-width-medium --border-width-thin --color-bg-elevated --color-bg-hover --color-border-default --color-error-text --color-text-primary --color-text-tertiary --duration-fast --duration-normal --elevation-overlay --focus-ring --font-sans --radius-md --radius-sm --size-control-sm --size-icon-sm --size-touch-target --space-1 --space-2 --space-3 --state-disabled-opacity --text-small --text-xs --tracking-label --transition-enter --transition-exit --weight-semibold

Verified contrast

The build measures each pair for the defaults and for every tone, variant and state that reassigns a token, over page and card surfaces. The ratios below are the worst case in each mode; a pair below its minimum stops the build.

Menu contrast pairs
UsePairLightDarkMinimum
menu item--mp-menu-fg on --mp-menu-bg13.9312.507.0
menu item, focused--mp-menu-fg on --mp-menu-item-bg-hover12.5110.584.5
danger item--mp-menu-danger on --mp-menu-bg6.205.564.5
group label--mp-menu-label on --mp-menu-bg5.124.514.5

Source