RZREDZ.UI

Menus

A menu is a short list of actions or choices that opens from a button: the browser's popover, placed beside the button by CSS anchor positioning, driven by the keyboard as the WAI-ARIA menu button.

The button opens the menu with the browser's command - commandfor names the menu, command="toggle-popover" opens and closes it - and the library keeps its aria-expanded, which Firefox does not give such a button. No script is needed to open a menu; the library adds the arrow keys.

<button class="btn" type="button" commandfor="menu-actions-list" command="toggle-popover" aria-haspopup="menu"><i class="bi bi-three-dots" aria-hidden="true"></i>Actions</button>
<div id="menu-actions-list" class="menu" popover role="menu" aria-label="Actions">
	<button class="menu-item" type="button" role="menuitem"><i class="bi bi-pencil" aria-hidden="true"></i>Edit</button>
	<button class="menu-item" type="button" role="menuitem"><i class="bi bi-files" aria-hidden="true"></i>Duplicate</button>
	<button class="menu-item" type="button" role="menuitem" aria-disabled="true"><i class="bi bi-archive" aria-hidden="true"></i>Archive</button>
	<a class="menu-item" href="#menu-actions" role="menuitem"><i class="bi bi-box-arrow-up-right" aria-hidden="true"></i>Open on the site</a>
	<hr class="menu-divider">
	<button class="menu-item menu-item-danger" type="button" role="menuitem"><i class="bi bi-trash3" aria-hidden="true"></i>Delete</button>
</div>

Choices and headers

A choice of one is a set of menuitemradio items, the chosen one aria-checked="true" with a check drawn after it. menu-header titles a part of the menu. menu-start lines the menu up with its button's start edge instead of its end.

<button class="btn btn-text" type="button" commandfor="menu-choice-list" command="toggle-popover" aria-haspopup="menu"><span class="dot dot-success"></span>All sites<i class="bi bi-chevron-down" aria-hidden="true"></i></button>
<div id="menu-choice-list" class="menu menu-start" popover role="menu" aria-label="Work context">
	<div class="menu-header">Work context</div>
	<button class="menu-item" type="button" role="menuitemradio" aria-checked="true"><i class="bi bi-grid-3x3-gap" aria-hidden="true"></i>All sites</button>
	<button class="menu-item" type="button" role="menuitemradio" aria-checked="false"><i class="bi bi-globe2" aria-hidden="true"></i>lagoon.example</button>
	<button class="menu-item" type="button" role="menuitemradio" aria-checked="false"><i class="bi bi-globe2" aria-hidden="true"></i>northbay.example</button>
</div>

A menuitemcheckbox chosen flips its aria-checked, and a menuitemradio in a role="group" checks itself and unchecks the others of its group; the menu stays open for the next choice, and the page hears redz:check with detail.item and detail.checked. A menuitemradio outside a group is a choice of one, as above: it checks itself and closes the menu.

<button class="btn" type="button" commandfor="menu-checks-list" command="toggle-popover" aria-haspopup="menu"><i class="bi bi-layout-three-columns" aria-hidden="true"></i>Columns<i class="bi bi-chevron-down" aria-hidden="true"></i></button>
<div id="menu-checks-list" class="menu" popover role="menu" aria-label="Columns">
	<button class="menu-item" type="button" role="menuitemcheckbox" aria-checked="true">Guest</button>
	<button class="menu-item" type="button" role="menuitemcheckbox" aria-checked="true">Tour</button>
	<button class="menu-item" type="button" role="menuitemcheckbox" aria-checked="false">Pickup</button>
	<div class="menu-header" id="menu-checks-sort">Sort by</div>
	<div role="group" aria-labelledby="menu-checks-sort">
		<button class="menu-item" type="button" role="menuitemradio" aria-checked="true">Date</button>
		<button class="menu-item" type="button" role="menuitemradio" aria-checked="false">Name</button>
	</div>
</div>

The items of an open menu. :focus-visible is where the arrow keys are; aria-current="true" marks the page a menu of links is on.

KeyOn the buttonIn the menu
Enter, SpaceOpens the menu, the focus on the checked or the first itemRuns the item and closes the menu
↓ / ↑Opens the menu on the first / the last itemThe next / the previous item, round the ends
Home / End-The first / the last item
A letter-The next item that begins with it
Esc-Closes the menu, the focus back on the button
Tab-Closes the menu and moves on
  • The menu is popover with role="menu" and a name; its items are menuitem, menuitemradio or menuitemcheckbox. A list of site sections is navigation, not a menu - use links.
  • The button carries aria-haspopup="menu"; the library keeps its aria-expanded, and the browser moves the focus back to it on close and closes the menu on a click outside or Esc.
  • Where an engine does not put the menu beside its button - no anchor positioning below Firefox 147 and Safari 26, no anchor from a popover's button in Chrome 130-132, a table cell in Chrome 135-136, the bottom of a long page in Safari 26 - js/menu-place.js places it, again when the page scrolls or the menu or its button changes size, and the probes record each such place.

From css/components/menu.css, which declares no custom property of its own.

It reads the theme's --redz-space-4, --redz-border, --redz-radius-12, --redz-bg-raised, --redz-shadow-2, --redz-text, --redz-space-8, --redz-text-muted, --redz-fs-12, --redz-control-height, --redz-radius-8, --redz-bg-hover, --redz-text-faint, --redz-primary, --redz-danger, --redz-motion, --redz-ease.

Bootstrap 5.3REDZ.UIChangeNote
dropdown-removeno wrapper: the menu flips by itself
dropdown-center-removeno wrapper: the menu flips by itself
dropdown-dividermenu-dividerrename
dropdown-headermenu-headerrename
dropdown-itemmenu-itemrenamerole="menuitem"
dropdown-item-text-reviewmenu-header, or plain text
dropdown-menumenurenamewith popover and role="menu"
dropdown-menu-dark-removethe theme sets it
dropdown-menu-end-removethe menu meets its button's end edge by default
dropdown-menu-startmenu-startrename
dropdown-toggle-reviewthe button: commandfor + command="toggle-popover" + aria-haspopup="menu"; a chevron is an icon
dropdown-toggle-split-reviewa btn-group of the action and a btn-icon that opens the menu
dropend-removeno wrapper: the menu flips by itself
dropstart-removeno wrapper: the menu flips by itself
dropup-removeno wrapper: the menu flips by itself
dropup-center-removeno wrapper: the menu flips by itself
data-bs-toggle="dropdown"commandfor="ID" command="toggle-popover" aria-haspopup="menu"triggerthe menu gets popover and role="menu"
data-bs-placement-removeanchor positioning places and flips the menu
data-bs-offset-removeanchor positioning places and flips the menu
data-bs-auto-close-removeanchor positioning places and flips the menu
data-bs-display-removeanchor positioning places and flips the menu
data-bs-reference-removeanchor positioning places and flips the menu
data-bs-boundary-removeanchor positioning places and flips the menu
data-bs-popper-config-removeanchor positioning places and flips the menu
bootstrap.Dropdownmenu.showPopover(), menu.hidePopover(), menu.togglePopover()trigger
show.bs.dropdowntogglerenamethe popover's toggle event; event.newState is "open" or "closed"
shown.bs.dropdowntogglerenamethe popover's toggle event; event.newState is "open" or "closed"
hide.bs.dropdowntogglerenamethe popover's toggle event; event.newState is "open" or "closed"
hidden.bs.dropdowntogglerenamethe popover's toggle event; event.newState is "open" or "closed"