Skip to main content

Combobox

A practical Accessibility Field Guide page for checking combobox fields, autocomplete suggestions, selected values, keyboard behavior, focus, and ARIA state.

A cafe wall menu lists drink options and prices above a counter.
Photo: Menu on Wall in Cafe via Pexels — https://www.pexels.com/photo/menu-on-wall-in-cafe-19933489/
View full screen Download image

A combobox lets someone type or choose a value from a related set of options.

That can be useful for search fields, autocomplete inputs, filters, long dropdown lists, address fields, people pickers, and typeahead controls.

It can also become one of the easiest components to make confusing.

A useful combobox needs a clear label, predictable typing behavior, understandable suggestions, keyboard access to the popup, a selected value that is exposed correctly, and ARIA that matches what the component actually does.

The goal is not to turn every select field into a custom autocomplete.

The goal is to use a combobox when typing and suggestions genuinely help the task, and to make the input, popup, focus, and selected value understandable for everyone.

The common project moment

A form has a field with many possible values.

Maybe the user has to pick a county, search for an agency, choose a payee, select a category, find a person, or enter an address.

A normal dropdown starts to feel too long. Someone suggests autocomplete because it looks cleaner and should help users find the answer faster.

In the design file, the pattern seems straightforward:

  • one text field;
  • a placeholder or label;
  • a list of matching suggestions;
  • one highlighted option;
  • a selected value after the user chooses;
  • maybe a clear button or a loading state.

But the implementation may not be as simple as the mockup:

  • the field has no real label;
  • the suggestions only work with a mouse;
  • arrow keys move focus visually but not programmatically;
  • screen reader users do not know suggestions appeared;
  • the highlighted option is not the selected value;
  • typing changes the list but the current state is not announced;
  • aria-expanded, aria-controls, or aria-activedescendant are missing or stale;
  • the user cannot clear, escape, or recover from the control.

That is where comboboxes get expensive.

The visual design says, "type here and choose from these suggestions."

The code needs to expose the same relationship without trapping the user inside the component.

Start by asking whether a combobox is the right pattern

Before checking ARIA, ask whether the component should be a combobox at all.

A combobox can help when:

  • the list is long enough that scrolling through every option is painful;
  • users know enough to type part of the value;
  • suggestions reduce errors or speed up selection;
  • the field supports a real search or filter task;
  • the selected value needs to stay visible after choosing.

A combobox may be a poor fit when:

  • there are only a few options;
  • the user must compare all choices before deciding;
  • the options are unfamiliar codes or names;
  • the field behaves like navigation instead of data entry;
  • a native select, radio group, checkbox group, or search field would be clearer.

This matters because comboboxes have more moving parts than they appear to have.

If the task does not need typing plus suggestions, a simpler native pattern is often easier to understand and easier to make accessible.

Keep the label, input, popup, and value clear

A combobox is not just a styled text box.

At minimum, the user needs to understand:

  • what the field is asking for;
  • whether typing is allowed;
  • whether suggestions are available;
  • whether the popup is open or closed;
  • which option is currently highlighted;
  • which value has actually been chosen;
  • whether free text is allowed or the value must come from the list.

The label should be visible and programmatically associated with the input.

Placeholder text is not enough. It disappears when someone starts typing, and it often does not give enough context for review, correction, or error recovery.

The popup also needs a clear relationship to the input. If suggestions appear visually, the component should expose that the input controls a listbox, grid, dialog, or other popup pattern, depending on how it is built.

The selected value should be different from the highlighted suggestion.

A highlighted option is where the user is currently moving.

A selected value is what the field will submit or save.

If those states blur together, users may not know what the form is going to do.

Keyboard behavior is part of the component contract

A combobox should not depend on pointer movement.

At a practical review level, check whether a keyboard user can:

  • move focus to the field in a predictable order;
  • type into the field when typing is supported;
  • open the suggestions when expected;
  • move through suggestions with arrow keys;
  • choose a suggestion with Enter or another documented key;
  • dismiss the popup with Escape;
  • move away with Tab without getting trapped;
  • clear or change the selected value;
  • submit the form only when the intended value is present.

The exact keyboard model can vary by combobox type.

Some comboboxes open suggestions automatically while the user types. Some open with a button. Some allow free text. Some require the chosen value to match an option. Some use a simple listbox. Others use a grid or more complex popup.

That is why the team should not copy ARIA attributes from an example and assume the keyboard behavior is done.

The behavior has to be tested.

If arrow keys only move a visual highlight, but assistive technology does not receive the active option, the control is not really working.

If Tab jumps into hidden options or traps the user inside the popup, the component is not ready.

Focus should stay predictable

Comboboxes often create focus confusion because the user is interacting with two things that look separate:

  • the text input;
  • the suggestion popup.

In many implementations, DOM focus stays on the input while aria-activedescendant points to the active option in the popup.

That can be fine, but it has to be intentional.

The user should be able to tell where they are, what option is active, and what will happen if they press Enter.

Watch for these problems:

  • focus disappears when the popup opens;
  • the active option is shown only by color;
  • focus moves into the popup but cannot return to the input cleanly;
  • the clear button appears in the tab order unpredictably;
  • selected chips or tokens are reachable but not removable by keyboard;
  • validation errors appear after selection but focus does not help the user recover.

A combobox should not make the user guess whether they are editing text, moving through options, or committing a value.

Announce changes that affect the task

Autocomplete controls often change while the user types.

That creates a communication problem.

If suggestions appear, disappear, load, or narrow down, users who cannot see the popup still need enough information to continue.

Useful states may include:

  • suggestions are available;
  • no results found;
  • loading suggestions;
  • a required selection is missing;
  • the typed value is invalid;
  • the selected value was removed.

Do not over-announce every keystroke or every small visual update.

The point is not to make the component noisy.

The point is to make meaningful changes available when they affect the next action.

For example, "No matching counties found" is useful when the list is empty.

"5 suggestions available" may be useful when the list appears after typing.

A silent empty popup is not useful.

ARIA attributes only help when they match real behavior

ARIA can describe a combobox, but it cannot make a broken interaction work.

Common attributes and relationships may include:

  • role="combobox" on the correct element;
  • an accessible name from a visible label;
  • aria-expanded that changes when the popup opens or closes;
  • aria-controls pointing to the popup element;
  • aria-autocomplete when suggestions are based on user input;
  • aria-activedescendant when focus stays on the input and the active option is managed in the popup;
  • aria-selected or equivalent state on options when the pattern uses selection.

Those attributes need to stay synchronized with the interaction.

If the popup is open, aria-expanded should not still say false.

If the active option changes, aria-activedescendant should not point to an old or missing element.

If the component lets users type any value, it should not pretend the user selected an option from a fixed list.

If the field requires an option from the list, the error recovery should make that clear.

The review question is simple:

Does the accessibility tree tell the same story as the screen?

Common trail hazards

Comboboxes tend to fail in a few repeatable ways:

  • using a styled div as the input instead of a real editable control;
  • relying on placeholder text instead of a label;
  • showing suggestions visually without exposing the popup relationship;
  • using mouse hover as the only way to preview or choose options;
  • treating visual highlight, active descendant, and selected value as the same thing;
  • losing focus when results load;
  • making Escape close the whole modal or page layer instead of just the combobox popup;
  • submitting partial text when the field required a selected option;
  • clearing the field without announcing that the value changed;
  • hiding errors or instructions inside the suggestion popup.

Most of these are not solved by adding one ARIA attribute.

They are behavior, focus, labeling, state, and recovery problems.

A small habit that helps

Test the combobox without a mouse before reviewing the code.

Start with the visible label.

Then use only the keyboard:

  1. Tab to the field.
  2. Type a few characters.
  3. Open or review the suggestion list.
  4. Move through options.
  5. Select one.
  6. Clear or change it.
  7. Trigger an error state.
  8. Leave the field and come back.

While doing that, ask what the component is promising at each step:

  • Am I typing?
  • Am I choosing?
  • Am I moving through suggestions?
  • What is active?
  • What is selected?
  • What will be submitted?

If the answer is unclear visually, with the keyboard, or in the accessibility tree, the component needs more work before ARIA can be trusted.

Combobox issues often touch several WCAG criteria because the pattern combines labels, relationships, keyboard behavior, focus, state, and error recovery.

Useful trail markers:

  • 1.3.1 Info and Relationships — the label, input, popup, active option, and selected value need understandable relationships.
  • 2.1.1 Keyboard — users need to operate the field, popup, options, clearing, and selection without a mouse.
  • 2.1.2 No Keyboard Trap — the popup should not trap focus or prevent the user from leaving the component.
  • 2.4.3 Focus Order — focus should move through the field, popup controls, selected tokens, errors, and next fields in a meaningful order.
  • 2.4.7 Focus Visible — the field, popup control, active option, clear button, and selected tokens need visible focus or active indication.
  • 3.2.1 On Focus — receiving focus should not unexpectedly submit, navigate, or commit a value.
  • 3.2.2 On Input — changing the field should not create unexpected context changes without warning.
  • 3.3.2 Labels or Instructions — the field needs enough instruction for users to know what value is expected and whether free text is allowed.
  • 4.1.2 Name, Role, Value — the component needs an accessible name, role, expanded state, active option, and selected value that match the interaction.
  • 4.1.3 Status Messages — important changes such as loading, no results, or validation feedback may need to be announced without moving focus.
  • Native HTML First — start with the simplest native control that supports the task before building a custom autocomplete.
  • Button vs Link — use real buttons for opening, clearing, and committing actions; do not turn navigation links into fake combobox controls.
  • Accessible Names — the field, clear button, and popup controls need useful names.
  • Name Role Value — comboboxes are a strong example of why role, state, selected value, and behavior need to agree.
  • ARIA Is Not Duct Tape — ARIA should describe working behavior, not cover for missing keyboard support, focus management, or state updates.
  • Developer Component Checklist — use the checklist to review labels, roles, states, keyboard behavior, focus, and handoff notes before review.
  • Accordion — compare when content should expand/collapse instead of being selected from an autocomplete popup.
  • Tabs — compare when users should switch between peer panels instead of typing or choosing from suggestions.
  • Status Messages and Alerts — suggestion counts, loading states, no results, and validation feedback may need status-message behavior.
  • Forms and Labels — comboboxes usually fail as form controls before they fail as ARIA examples.

The WAI-ARIA Authoring Practices Guide includes a detailed combobox pattern with role, state, property, and keyboard guidance.

Use it as a reference, not a shortcut.

The APG pattern helps explain how a combobox can work.

It does not prove that a custom implementation is accessible in the product.

The product still needs to be tested with the actual label, popup, data, keyboard behavior, validation, focus management, and assistive technology behavior users will encounter.

  • Accessibility Glossary — for plain-language definitions of common accessibility terms used across this guide.

What to do next

When reviewing a combobox, start with the task instead of the widget.

Ask whether the user really needs typing plus suggestions.

If a simpler native control works, use it.

If a combobox is the right pattern, test the full interaction: label, typing, popup, active option, selected value, keyboard behavior, focus, errors, and announcements.

Then check whether the ARIA tells the same story as the component.