Skip to main content
PimentCSS v1.0.1, what's new
Home

Menu & dropdown

Menu lists, dropdown panels, and keyboard-friendly disclosure.

Overview

.menu is a bordered list of .menu__item rows (280px max width, scrollable list). Use .menu--caret or .menu--caret-left for popover pointers. .dropdown wraps a field-like trigger, hint, and a floating .dropdown__panel that contains a menu.

PartClassRole
Menu.menuListbox container
List.menu__listScrollable column of items
Item.menu__itemRow button or option
Selected.menu__item--selectedActive row (action surface)
Caret.menu--caretCentered popover arrow
Dropdown.dropdownLabel + trigger + panel
Trigger.dropdown__triggerOpens panel (aria-expanded)
Panel.dropdown__panelAbsolute menu host (z-index: 100)

Prerequisites

  • PimentCSS installed, Installation.
  • Input fields, dropdown triggers extend .field (Input fields).
  • Icons, row icons via ph() (Phosphor in this doc).
  • Depth, panels use box-shadow: var(--shadow-md) (Depth & shadows).

Rows are <button type="button"> elements. Doc-only .menu__item--hover previews hover; live UIs use :hover. Selected pairs with aria-selected="true". Disabled rows use the disabled attribute.

Default
Hover
Disabled
Not selected
Selected

Plain menu, centered caret (.menu--caret), or left-aligned caret (.menu--caret-left). Items can be text-only or include leading and trailing icons.

None

Dropdown (caret)

Left (caret)

Closed and open states below are static previews. The live example wires toggle, selection, arrow keys, Home/End, Escape, and outside click (same pattern as the date picker and autocomplete).

Add data-dropdown-live on .dropdown and call wireAllDropdowns() after load. Copy menu-dropdown-behavior.ts into your app.

Class reference

ClassDescription
.menuMenu container (border, max 17.5rem)
.menu__listScrollable flex column
.menu__itemRow: flex, min-height field, dividers
.menu__item--hoverDoc-only hover preview
.menu__item--selectedSelected row (action colors)
.menu__item--disabledDisabled row
.menu__item-icon24px icon slot
.menu__item-labelFlexible label column
.menu--caretTop-center pointer pseudo-elements
.menu--caret-leftPointer offset to the left
.dropdownVertical stack: label, hint, trigger, panel
.dropdown__hintCaption under label
.dropdown__triggerField-styled opener
.dropdown__valueTrigger label (--filled when set)
.dropdown__chevronRotates when open
.dropdown__panelHosts .menu, shadow md
.dropdown--openShows panel, focus ring on trigger

Customize (Sass)

  1. Override list width, item padding, and max height before importing components.
    @use "pimentcss-design-system" with (
      $menu-width: 20rem,
      $menu-item-padding-x: 1rem,
      $menu-item-padding-y: 0.5rem,
      $menu-max-height: 18rem
    );
  2. Run after editing _menu.scss or _dropdown.scss.
    npm run build:css

Accessibility (RGAA / WCAG)

Menus and listboxes

  • Listbox, use role="listbox" on .menu and role="option" on items; label with aria-label or aria-labelledby.
  • Selection, set aria-selected="true" on the active option; do not rely on background color alone.
  • Disabled, use the native disabled attribute on buttons (not click handlers only).
  • Dropdown trigger, use a button with aria-expanded and aria-haspopup="listbox".
  • Keyboard, Arrow Up/Down, Home/End, Enter, and Escape on the live dropdown; close on outside click for pointer users.
  • Values, use data-label for visible trigger text and data-value for the stored value when they differ.
  • Controls, aria-controls on the trigger must reference the listbox id.
  • Focus, :focus-visible ring is built into .menu__item and the field trigger.

Next steps