New Components

Dropdown list

The dropdown list allows a value to be chosen from a set of options displayed on demand. Under this single name sit four distinct constructions, from the native element to the fully rebuilt pattern: native list, select-only combobox, filtering combobox and multiple selection. The choice commits the whole of the code to write and maintain, and must be made knowingly.

When to use a dropdown list

  • A choice from a closed list: the possible values are known in advance and the user has to pick one.
  • A long list: beyond seven or eight entries, a dropdown saves space and reading.
  • A very long list: with filtering, when typing three letters beats scrolling a hundred lines.

When not to use one

  • Two or three options: radio buttons show everything at once and cost one click less.
  • A binary choice: a checkbox or a toggle says better that something is turned on or off.
  • A free value: if the user can type whatever they want, it is a text field.

Modes of action

  • Mouse: a click opens the list, a second click commits the value.
  • Keyboard: the list opens with Enter, Space or an arrow. Arrows move through it, Enter commits, Escape cancels.
  • Screen reader: the native select is exposed with no effort. The ARIA variants rest on role="combobox", role="listbox" and aria-activedescendant.

Content

  • A visible label: the displayed value is not a label, it changes.
  • Distinct labels: two options with the same wording become impossible to tell apart by voice.
  • A predictable order: alphabetical, chronological or by frequency, but never random.

Keywords

  • combobox: the role of a control pairing a current value with a list of options.
  • aria-activedescendant: designates the current option without moving DOM focus. Never mix this technique with real focus.
  • aria-expanded: says whether the list is open or closed. It sits on the element holding focus.
  • aria-multiselectable: states that a listbox accepts several values.

Native dropdown list

The native select stays the first choice: exposure, keyboard, mobile and local format all come for free, with no script.

  • No ARIA role is added: doubling it would produce a contradictory announcement.
  • The label is visible and bound with for. Options are grouped with optgroup as the list grows.

Select-only combobox

Only use it when the native select cannot do the job: multi-line options, icons, rich formatting.

  • DOM focus never leaves the button. aria-activedescendant designates the current option.
  • aria-labelledby points at the field label, and only that: the value is the content of the button, exposed as the value of the component. Putting it in the name too would have it heard twice.
  • No live region is added: collapsing changes aria-expanded on the element holding focus, and the component is read again with its new value.
  • The list opens with the mouse and with the keyboard alike. Enter and Space commit, Escape and Tab cancel.

Filtering combobox

For long lists: the user types, the list narrows down.

  • The field carries aria-autocomplete="list": typing filters, it never completes the text in the user place.
  • The open button is a real button, in the tab order. A tabindex="-1" would make it a mouse-only command.
  • When no option matches, the message takes the place of the list but stays OUTSIDE the listbox: a listbox may only own options, any other element inside it is pruned from the accessibility tree (WCAG 1.3.1 and 4.1.3).
  • The number of results is announced after a 500 ms pause, so as not to cut across the typing echo.

Multiple selection

When several values can be held at the same time.

  • The list carries aria-multiselectable="true" and every option carries aria-selected, including at false: without it, nothing says the option is selectable.
  • The trigger is a disclosure button, not a combobox. A combobox carries one single value: the screen reader would then present the active option as that value, without saying whether it is selected. The summary of the choices is bound to the name of the button with aria-labelledby, and checkboxes that are always visible are a different pattern, not a dropdown list.
  • Selection is signalled by a drawn tick, not by colour alone (WCAG 1.4.1).
  • The summary of the values held is announced by a live region, with no focus move.

Screen reader

  • The native select stands on its own: it is the most reliable variant across browser and screen reader pairs.
  • On the ARIA variants, DOM focus stays in one single place. The two techniques, real focus and aria-activedescendant, are never mixed.
  • The current option needs a visual marker of its own, distinct from selection and contrasting with it (WCAG 1.4.11).
  • Every announcement goes through a live region present from page load, and empty.

The keyboard interactions differ according to the construction chosen. With the native element, they are handled by the browser. With the rebuilt patterns, they must be implemented in full.

Native dropdown list

Keyboard interactions for the native dropdown list
Key Function
Tab Moves focus to the component.
Up and Down Arrow Open the list, or change the retained value depending on the browser and the system.
Characters Typeahead search: moves the selection to the first option beginning with the characters typed.
Enter Retains the active option and closes the list.
Escape Closes the list without changing the value.

Select-only combobox

Keyboard interactions for the select-only combobox
Key Function
Tab Moves focus to the combobox. The list is not a tab stop.
Enter or Space Opens the list. When the list is open, retains the active option and closes it.
Down Arrow Opens the list, or moves the active option to the next one.
Up Arrow Opens the list, or moves the active option to the previous one.
Home and End Move the active option to the first or the last option of the list.
Characters Typeahead search: moves the active option to the first option beginning with the characters typed.
Escape Closes the list without changing the value.

Filtering combobox

Keyboard interactions for the editable combobox
Key Function
Tab Moves focus to the input field. The opening button is not a tab stop.
Down Arrow Opens the list, or moves the active option to the next one.
Up Arrow Opens the list with the active option on the last one, or moves the active option to the previous one.
Alt + Down Arrow Opens the list without moving the active option.
Alt + Up Arrow Retains the active option and closes the list.
Enter Retains the active option and closes the list. When no option is active, validates what has been typed.
Escape Closes the list without retaining an option. A second press may clear the content of the field.
Text editing keys Entering and correcting the value: characters, cursor movement, deletion.

Multiple selection

Keyboard interactions for the multi-select combobox
Key Function
Tab A single tab stop, the button. Once the list is expanded, focus moves into it: that is what has the state of each option announced. Tab closes it, gives focus back to the button and keeps the choices.
Enter or Space Expands the list when it is collapsed. Inside the list, ticks or unticks the current option without closing, which allows several to be chosen in succession.
Up and Down Arrow Expand the list when it is collapsed, then move the current option.
Home and End Take the current option to the first or the last item of the list.
Escape Collapses the list. The choices made are kept: with multiple selection they are taken as they go, there is no final commit to abandon.
Character keys First-letter search: keystrokes gather for 500 ms and take the current option to the first label starting with that text.

Note: in the first three constructions, DOM focus never leaves the combobox while the list is being traversed, because moving it would break typing on the filtering variant. The movement the user perceives is a visual focus, handled by aria-activedescendant. Multiple selection does the opposite, and it has to: focus moves into the listbox, otherwise screen readers do not say whether the active option is selected. Inside, the current option is still designated by aria-activedescendant.