Search topics
Autocomplete fields with silent, mouse-only suggestions
The suggestions under a type-ahead field are a plain list with click handlers or a CSS highlight, so a keyboard can't pick them and a screen reader never says they are there.
li.classList.toggle('active', i === active) The problem
Keyboard users can't pick a suggestion, and screen reader users can't tell that suggestions appeared, which one is highlighted, or that nothing matched.
A travel site's booking form has a Destination field. Type "por" and a list drops down under it: Porto, Portland, Portsmouth, with a line above it saying "3 suggestions". With a mouse, a click on Portland fills the field. With a keyboard, it depends on the build. In one version the arrow keys do nothing, and Tab leaves the field for the Search button, so the list can't be used at all. In another, the down arrow moves a blue highlight through the cities and Enter picks one, but a screen reader says nothing as it moves, or only reads back "por". Type "pxq" and the line changes to "No destinations found", and that is silent too.
Success Criterion 2.1.1 asks that everything a mouse can do can be done with a keyboard. In the first version, the suggestions are li elements with a click handler: they can't take focus and no key reaches them. Success Criterion 4.1.2 asks that a control's role and state, and anything the user can change, are available to assistive technology. In the second version, the field is still announced as a plain text field, the list has no role, and the highlight is a CSS class: the keyboard works, but the browser has nothing to tell a screen reader about which suggestion is highlighted or that a list is open. The count line is a status message, which Success Criterion 4.1.3 asks to be announced without moving focus, and it is a plain p.
Type-ahead fields often lead into the most important step of a form, such as a destination, an address or a product. On a phone, the list can open under the on-screen keyboard, so even sighted users may depend on the count line to know there is anything to pick.
4 of 10 groups affected
- No vision (affected)
- Low vision (affected)
- Colour vision (not affected)
- No hearing (not affected)
- Hard of hearing (not affected)
- No speech (not affected)
- Motor (affected)
- Reach, strength (not affected)
- Cognitive (affected)
- Seizures (not affected)
- Limited manipulation Keyboard and switch users can't reach the suggestions, so they have to type the whole name exactly, and a spelling slip gives no match.
- Without vision Screen reader users aren't told that suggestions appeared or which one is highlighted, and don't hear when nothing matched, so they may send a half-typed word.
- Limited vision Screen magnifier users zoomed in on the field may not see the list open below it, and a highlight drawn only as a pale fill can vanish in forced colors.
- Limited language, cognitive and learning abilities People who rely on suggestions to spell a place or product name lose that help when they can't pick from the list.
A scan loads the page and finds a labelled text field. The list doesn't exist until someone types, so there is nothing for it to check, and a list that does exist is markup with no ARIA to be wrong. AI assistants asked for an autocomplete often write exactly the second version: keydown handlers and an active class, sometimes with role="listbox" added to the list but no aria-activedescendant on the field, which still leaves the highlight silent. Others move focus into the list on the down arrow, so typing another letter goes nowhere. Only typing, arrowing and listening shows whether the list works.
Try it
Type por in Destination, press the down arrow, then Enter.
Can you pick Portland without the mouse? The panel shows what a screen reader says as you type and move. Try pxq too, which matches nothing.
Broken Can you fix this?
Screen reader says:
(Tab to Destination)
The fix
Make the field a combobox whose arrow keys move through suggestions exposed as options, and announce what the list says.
- 1Keep focus in the field; the arrow keys move a highlight that assistive technology can see.
- 2Say whether the list is open, and announce any count or no-match line.
- 3Enter picks and Escape closes; a click or tap picks the same way.
Suggestions that only a click can pick
<label for="dest">Destination</label><input id="dest" type="text" autocomplete="off"><p id="dest-count"></p><ul id="dest-list" class="suggestions" hidden></ul>An ARIA combobox
<label for="dest">Destination</label><input id="dest" type="text" role="combobox" autocomplete="off" aria-autocomplete="list" aria-expanded="false" aria-controls="dest-list"><p id="dest-count" role="status"></p><ul id="dest-list" role="listbox" aria-label="Destinations" hidden></ul>Why this fix: Style from the state, not a class
The suggestions are list items with a click handler. They can't take focus, no key reaches them, and nothing tells a screen reader they appeared.
Focus never leaves the field, so typing another letter still works. The field is announced as a combo box that says whether its list is open, and aria-activedescendant points at the highlighted option, so each arrow press reads that city out. Enter and a click both fill the field, Escape and leaving the field close the list, and the count line is a status region that is in the page from the start, so "3 suggestions" and "No destinations found" are announced once typing pauses. The transparent outline turns into a real one in forced colors, where the background fill is dropped.
Both pass 2.1.1 and 4.1.2. Use the ARIA combobox: it behaves the same in every browser, its list zooms and can be drawn for forced colors, it can show and announce a count, and the datalist's gaps are in the browser, where no code of yours can close them. The cost is the script above, which is yours to test and maintain. A datalist is a reasonable shortcut for a plain list of words on an internal tool whose browsers and screen readers you know, where the gaps above don't reach anyone who uses it.
If the list is short and the answer must be one of its entries, such as a country, a native select may serve better than any combobox. An autocomplete suits a long list, or one where people may type something that isn't on it.
Don't move DOM focus into the list. With focus on an option, the next letter typed goes nowhere, and screen readers leave their editing mode. Keep focus in the field and move aria-activedescendant. Don't put aria-live on the list either: every city would be read on each keystroke.
The count line must be in the page before the first keystroke, and outside anything your framework re-renders with the list, or its first change is not announced. Some screen readers read nothing when the same words are written twice; if "3 suggestions" can follow "3 suggestions", clear the line before writing it again.
Some combobox components in UI libraries implement this pattern, and some ship the second Before with an accessible name. Check any library by typing, arrowing and listening, as in the steps below, before you trust its documentation. For other dropdown failures, see search panels that close on Tab and drop keyboard focus and search and filter results that update without a word.
Fixing this with an AI coding assistant? Get this guide as Markdown
Verify the fix
5 checks, no mouse.
Test with: Keyboard, Screen reader, Zoom, Forced colors
Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the shared field or autocomplete component changes.
Limits
This is a starting pattern for a list autocomplete, not for comboboxes that complete text inline, open a grid or a tree, or allow several choices. The snippets leave out fetching and matching. Test the complete journey, with your real data, in the browsers and assistive technology you support.
This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.
References
- ARIA APG: combobox (opens in a new tab)
- ARIA APG: combobox-autocomplete-list (opens in a new tab)
- WCAG Understanding: keyboard (opens in a new tab)
- WCAG Understanding: name-role-value (opens in a new tab)
- WCAG Understanding: status-messages (opens in a new tab)
- developer.mozilla.org: combobox_role (opens in a new tab)
- developer.mozilla.org: datalist (opens in a new tab)
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.