Components · Menus, lists and dividers

Menu

A menu is the list surface that opens from a button or action (Dropdown menu) or from a Select field (Exposed dropdown menu). The two differ only in the element that opens the surface, so they share one component.

Every example on this page is the real component, not a picture. Hover, click and tab to try it. Figma: Menu. Row content comes from List Item.

Playground

Choose a breakpoint, size, divider and selection type and the menu and its code update. The menu is live: hover a row, click to choose.

Breakpoint
Size
Divider
Selection
Row 3

Markup for this selection

HTML

Overview

A menu is the list surface that opens from a button or action (Dropdown menu) or from a Select field (Exposed dropdown menu). The two differ only in the element that opens the surface, so they share one component.

Menu has two sizes (Large and Small), three divider styles (middle-inset, full-width and none) and two selection types (Select and Multi Select). Row content (leading element, label, trailing element) comes from the List Item component; the menu draws the row, the divider, the hover and the check.

This documentation has three pages. Examples & Guidelines (this page) shows when and how to use a menu. Specifications holds the values: tokens, sizes, measurements, states and requirements. Code shows how to add one to a page.


Usage

When to use

Use a menu to show a temporary list of choices or actions. Use it:

  • As a Dropdown menu, opened by a button or another control, to list actions or choices
  • As an Exposed dropdown menu, opened by a Select field, to list the values the field can have

When not to use

Keep each label on one line

A row is one line high. A long label wraps and breaks the rhythm of the list, so shorten it or choose another component.

Do keep every label short enough for one line.
Do not write labels that wrap onto a second line.

Keep the list short

The menu shows up to 14 rows and then scrolls. A long list is hard to scan, so use it only when the user needs the full set.

Do keep the list to the choices the user needs.
Do not put a long list in a menu without a clear need: it scrolls.

For page navigation

A menu is not the header menu or a drawer. Use those for navigation between pages.

For two to five visible options

When the options are few and should always be visible, use eco-radio (one choice) or eco-checkbox (several).

Quick reference

The user…Use
picks one value in a form fieldeco-select (the closed field), opening a Menu (Exposed dropdown)
opens a list of actions or choices from a buttonMenu (Dropdown menu)
picks one of two to five visible optionseco-radio
picks any number of visible optionseco-checkbox

Do

  • Keep labels short so they fit one line.
  • Use Multi Select only when more than one choice is valid.
  • Let the opener set the menu width.
  • Set aria-selected to match the check.
  • Keep a disabled row in the list (with aria-disabled) when the user should know it exists.

Don’t

  • Use a menu for page navigation.
  • Put more than about 14 rows in without a clear need: the list scrolls.
  • Mix divider styles in one menu.
  • Hardcode colors or row heights: use the tokens and size classes.

Anatomy

Menu

  1. Surface. A white box with the elevation-b-80 shadow. It is as wide as the opener.
  2. Row. One option. 48px high on desktop and 40px on mobile (Large), with 16px side padding.
  3. Label. body-md (Large) or body-sm (Small), one line.
  4. Check icon. A check_circle on the chosen row. Multi Select shows a circle on every row. 24px on desktop Large, 20px otherwise.
  5. Divider. A 1px line inside the row height. Middle-inset keeps 16px on each side.

A scrollbar appears only when the list has more than 14 rows.


Variants

Three divider styles and two selection types. Use the Breakpoint toggle to preview Desktop (769px and up) and Mobile (below 769px). Sizes are under Sizes below.

Breakpoint

Dividers

Middle-inset keeps 16px on each side and is the default. Full-width runs edge to edge. No removes the line.

Selection

Select chooses one row and marks it with a check. Multi Select shows a circle on every row and a check on the chosen ones.

Scrolling

The menu shows up to 14 rows. With more, the list scrolls and a 12px scrollbar appears.


Sizes

Large is the default for forms and the Select field. Small is for compact surfaces. Both change at 769px: Large rows are 48px on desktop and 40px on mobile, Small rows 40px and 32px. The values are under Sizes in Specifications.

Breakpoint

Layout & Appearance

Alignment

Labels are left-aligned and the check icon sits at the right edge of the row. Use one divider style in a menu.

Placement

The menu opens directly under its opener. The opener owns the position and the open and close behavior; this page shows the surface only.

Width

The menu fills the width the opener gives it. For a Select field it is as wide as the field.

Appearance

A white surface with the elevation-b-80 shadow and square corners. Token names and values are under Design Tokens in Specifications.


Behavior

Hover

The row fill changes to surface-navigation-hover. In Multi Select an unselected row previews the check.

Focus

Rows are focusable. A 2px ring shows inside the row on keyboard focus. Arrow keys move between rows and skip a disabled row.

Selection

A click, Enter or Space chooses the row. Select replaces the choice; Multi Select toggles it.

Disabled row

A disabled row has text-disabled text and icon, no hover fill, and is not focusable. A click or Enter does nothing.

Dismissal

The opener closes the menu and returns focus to itself on Escape. All states are listed under States in Specifications.


Accessibility

All requirements are listed under Accessibility Requirements in Specifications.

Keyboard support

Tab reaches the rows. Up and Down arrows move between them, Enter or Space chooses, and Escape closes the menu through the opener.

Screen reader support

The list is a listbox and each row an option with aria-selected. Multi Select sets aria-multiselectable="true". A disabled row has aria-disabled="true".



References