UI + UX Selection And Choice standard

Listbox

Provide a labelled listbox with option roles, managed active focus, selected state, keyboard navigation, optional typeahead, clear selection policy, and no nested interactive controls inside options.

Decision first

Choose this pattern when the problem matches

Use when

  • Users choose one option from a visible static list.
  • A visible option list supports scanning, preview, or frequent switching better than a collapsed select.
  • The list is long enough to benefit from roving focus, typeahead, grouping, or scrolling.
  • The product needs a custom listbox because native controls cannot provide the required visible layout.

Avoid when

  • A native select, radio group, or checkbox group can satisfy the interaction.
  • The list is a popup controlled by a text field or button.
  • Rows need independent buttons, links, menus, checkboxes, or editable fields.
  • Options are too long, repeated, or semantically rich to work as a single option name.
  • The selection has high-stakes side effects and the design cannot separate focus from committed selection.

Problem it prevents

Users need to choose from a visible set of static options, but collapsed selects hide comparison and generic clickable lists do not expose focus, option count, or selected state.

Pattern anatomy

What a strong implementation has to make clear

User need

The available values should remain visible while users choose.

Pattern promise

Provide a labelled listbox with option roles, managed active focus, selected state, keyboard navigation, optional typeahead, clear selection policy, and no nested interactive controls inside options.

Required state

Empty or initial state with visible label and at least one option.

Recovery path

Screen readers announce only a long flattened option string because semantic headings or controls were placed inside the option.

Access contract

Use role listbox on the container and role option on every selectable item.

Quality bar

The difference between expert and weak execution

Strong implementation

Specific, visible, recoverable

  • A Role listbox has a visible label, five role options, one active row, one selected row, concise option names, and a status line explaining whether focus or selection changed.
  • A grouped city listbox uses group labels for countries and short city option names instead of repeating the country in every option.
  • A user arrows from Analyst to Support, hears the active option change, then presses Select active option to commit Support.
  • A user turns on selection-follows-focus for a low-risk preview list and sees that moving focus now updates the selected value immediately.
Weak implementation

Vague, hidden, hard to recover from

  • Each option row contains nested Edit and Delete buttons, making the listbox a broken table of actions.
  • Every option starts with the same long prefix such as United Kingdom office location, forcing users to listen through repeated text.
  • A high-stakes role assignment saves as soon as focus moves while the user is only exploring options.
  • A user tries to activate a Delete button inside an option, but assistive technology exposes the row only as one option string.
UI guidance
  • Render a labelled listbox container, visible options, active option styling, selected option state, optional grouped labels, empty or disabled states, and nearby help or error text.
  • Keep option content concise and non-interactive; use separate controls outside the listbox for actions such as edit, remove, move, select all, or clear.
UX guidance
  • Use a listbox when users benefit from seeing the available options while moving focus through the list and selecting one or more static values.
  • Make the selection model explicit because focus, active option, and selected option may be different states.
Implementation contract

What the implementation must handle

States

  • Empty or initial state with visible label and at least one option.
  • Focused listbox state.
  • Active option state distinct from selected state.
  • Selected option state.

Interaction

  • The listbox has a visible label or accessible name and contains or owns every option.
  • Each selectable option exposes one selected state using aria-selected or aria-checked consistently.
  • Active focus is represented by DOM focus on an option or by aria-activedescendant on the listbox.
  • Arrow keys move the active option; Home and End move to list boundaries when supported.

Accessibility

  • Use role listbox on the container and role option on every selectable item.
  • Provide a visible label and connect it with aria-labelledby when possible.
  • Use aria-selected or aria-checked consistently; avoid exposing both unless the two states mean different user-visible things.
  • Set aria-multiselectable true for multiple selection and expose state on every selectable option.

Review

  • Do users need the options visible all the time, or is this really a select or combobox?
  • Is focus movement separate from selection, and is that policy visible in the UI?
  • Are all option names short enough to be understood as one spoken string?
  • Do any options contain interactive controls that require a grid, table, menu, or toolbar instead?
Interactive lab

Inspect the states before you copy the pattern

Move focus through visible options

Move the active option, select it, try typeahead and Home or End, and compare preview focus with selection-follows-focus.

Listbox
Interactive demo is ready

Launch the live UI/UX lab when you want to inspect states, keyboard behavior, and common failure modes.

State To Inspect

Empty or initial state with visible label and at least one option.

Keyboard / Access

Tab moves focus to the listbox or selected option.

Avoid Generating

Using listbox when native select, radio buttons, or checkboxes would do the job with less risk.

Evidence trail

Source-backed claims behind this guidance

WAI-ARIA APG Listbox Pattern

W3C Web Accessibility Initiative - checked

APG defines listbox as a visible selectable option list, with single and multi-select behavior, focus versus selection, typeahead, Home and End, grouped options, selection state, and nested-interactive-content limits.

MDN ARIA listbox role

MDN Web Docs - checked

MDN documents the listbox role, option requirements, aria-selected, aria-activedescendant, aria-multiselectable, required and read-only states, native alternatives, and keyboard behavior.

Full agent/debug reference

Problem Context

  • The available values should remain visible while users choose.
  • Options are static enough to be represented as selectable choices rather than interactive row content.
  • Users need keyboard movement through options and a perceivable selected state.
  • The list may be long enough for typeahead, scrolling, Home and End, or grouping.
  • The product must decide whether moving focus only previews an option or also selects it.

Selection Rules

  • Choose a listbox when options should remain visible and users select one or more values from the list itself.
  • Use a native select when a compact closed single-choice control is sufficient.
  • Use a combobox when the list is a popup controlled by an input or button and the field value owns the interaction.
  • Use radio buttons or checkbox groups when the set is short and normal form controls communicate the job with less custom keyboard work.
  • Use multi-select when the product pattern is a compact searchable picker with selected chips or a selected-set review surface.
  • Use a grid, table, menu, or separate action toolbar when rows need buttons, links, checkboxes, toggles, or editable controls.
  • Keep option names short and move repeated category context into group labels or separate controls.
  • Make selection-follows-focus opt-in for low-risk preview contexts and avoid it for destructive, expensive, or externally visible changes.

Required States

  • Empty or initial state with visible label and at least one option.
  • Focused listbox state.
  • Active option state distinct from selected state.
  • Selected option state.
  • Selection-follows-focus enabled or disabled policy state.
  • Typeahead matched option state.
  • First option and last option states for Home and End movement.
  • Disabled option state.
  • Read-only listbox state.
  • Required no-selection validation state.
  • Grouped options state when categories are present.
  • Scrollable long-list state with preserved active visibility.

Interaction Contract

  • The listbox has a visible label or accessible name and contains or owns every option.
  • Each selectable option exposes one selected state using aria-selected or aria-checked consistently.
  • Active focus is represented by DOM focus on an option or by aria-activedescendant on the listbox.
  • Arrow keys move the active option; Home and End move to list boundaries when supported.
  • Typeahead moves focus to the next option whose name starts with the typed character sequence.
  • Single-select listboxes select at most one option; multi-select listboxes set aria-multiselectable and expose state on every selectable option.
  • Moving focus changes selection only when the interaction model explicitly uses selection-follows-focus.
  • Options are not containers for independent interactive controls.

Implementation Checklist

  • Confirm that users need a visible custom option list instead of native select, radio buttons, checkbox groups, combobox, or multi-select picker.
  • Choose single-select or multi-select and document whether selection follows focus.
  • Use role listbox on the container and role option on each option, or use a native control that exposes equivalent semantics.
  • Give the listbox a visible label with aria-labelledby or an accessible name with aria-label.
  • Use aria-activedescendant or roving DOM focus consistently and keep the active option in view.
  • Expose aria-selected or aria-checked consistently, and set aria-multiselectable for multi-select lists.
  • Implement Arrow keys, Home, End, typeahead, Space or Enter selection, required validation, disabled options, and read-only state.
  • Move interactive row actions outside the listbox or choose a grid or table pattern.
  • Test keyboard, screen reader, touch, high zoom, forced colors, long option names, repeated prefixes, grouping, scrolling, and dynamic option updates.

Common Generated-UI Mistakes

  • Using listbox when native select, radio buttons, or checkboxes would do the job with less risk.
  • Putting buttons, links, checkboxes, toggles, menus, or form fields inside options.
  • Treating focus and selection as identical without deciding whether selection follows focus.
  • Using long repeated option labels that hide the distinguishing words.
  • Leaving aria-activedescendant pointing to a removed or hidden option.
  • Failing to expose unselected state in a multi-select listbox.
  • Using a listbox as a command menu where options trigger actions instead of setting a value.

Critique Questions

  • Do users need the options visible all the time, or is this really a select or combobox?
  • Is focus movement separate from selection, and is that policy visible in the UI?
  • Are all option names short enough to be understood as one spoken string?
  • Do any options contain interactive controls that require a grid, table, menu, or toolbar instead?
  • Can keyboard users reach the first option, last option, a typed prefix, disabled options, and validation errors predictably?
Accessibility
  • Use role listbox on the container and role option on every selectable item.
  • Provide a visible label and connect it with aria-labelledby when possible.
  • Use aria-selected or aria-checked consistently; avoid exposing both unless the two states mean different user-visible things.
  • Set aria-multiselectable true for multiple selection and expose state on every selectable option.
  • Use aria-activedescendant only when the referenced active option exists and is owned by the listbox.
  • Do not place interactive descendants inside options because assistive technology treats option content as one name.
  • Keep option names concise and move repeated context into labels, groups, or separate controls.
  • Expose disabled, read-only, required, invalid, grouped, and scrolled states without relying on color alone.
Keyboard Behavior
  • Tab moves focus to the listbox or selected option.
  • Down Arrow moves focus to the next option.
  • Up Arrow moves focus to the previous option.
  • Home moves focus to the first option when supported.
  • End moves focus to the last option when supported.
  • Typing one or more characters moves focus to the next option whose name starts with the typed string.
  • Enter or Space selects the active option when selection does not automatically follow focus.
  • In multi-select listboxes, Space toggles the focused option and optional Shift or Control shortcuts extend or preserve selection according to the chosen model.
  • Escape should not clear committed selection unless the surrounding workflow explicitly defines that behavior.
Variants
  • Single-select listbox
  • Multi-select listbox
  • Scrollable listbox
  • Grouped listbox
  • Reorderable listbox
  • Horizontal listbox
  • Listbox with selection follows focus
  • Listbox with aria-activedescendant
  • Listbox with roving tabindex

Verification

Last verified: