Accessibility for Autocomplete Widgets
Apply aria-autocomplete, aria-expanded, role=listbox, and role=option to make the widget screen-reader friendly.
Accessibility for Autocomplete Widgets is a free React Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the React Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
The Combobox ARIA Pattern
The WAI-ARIA combobox pattern defines a specific set of roles and properties for autocomplete widgets. A combobox is an input element paired with a listbox popup. The pattern ensures that screen readers correctly announce the interactive behavior, available options, and current selection to users who cannot see the visual UI.
role=combobox on the Wrapper
Wrap the input in a div with role="combobox". This announces to assistive technology that the input has an associated popup list. Set aria-expanded={isOpen} on this wrapper to tell screen readers whether the suggestion list is currently visible or hidden.
Input ARIA Attributes
The input element itself should have: aria-autocomplete="list" (the popup contains a list of suggestions), aria-haspopup="listbox" (clicking or typing opens a listbox), aria-expanded={isOpen}, and aria-controls="suggestion-list-id" pointing to the id of the dropdown list element.
aria-activedescendant
aria-activedescendant on the input points to the id of the currently highlighted option. When selectedIndex is 0, set aria-activedescendant="option-0". Screen readers use this to announce which item is active without moving actual focus from the input. When no item is selected, remove the attribute or set it to an empty string.
The Suggestion List: role=listbox
The dropdown container element should have role="listbox" and a unique id matching the input's aria-controls. This role tells the accessibility tree that this element is a list of selectable options. The listbox receives focus indirectly via aria-activedescendant on the input.
Each Suggestion: role=option
Every suggestion item should have role="option" and a unique id such as option-0, option-1, etc. Add aria-selected={index === selectedIndex} to indicate which item is currently highlighted. Screen readers announce both the option content and whether it is selected when the user navigates with arrow keys.
Screen Reader Announcement
When the user presses ArrowDown and aria-activedescendant updates to option-1, VoiceOver announces something like "React hooks, 2 of 5". The screen reader reads the option text and its position in the list automatically from the ARIA markup. No additional live regions are needed for keyboard navigation.
Testing with VoiceOver and NVDA
Test with VoiceOver on macOS (Cmd+F5 to toggle) and NVDA on Windows (free download). Navigate to the input and start typing. Verify the screen reader announces the combobox role, the number of results found, and each option as you arrow through. Compare behavior against the WAI-ARIA Authoring Practices Guide examples.
Live Region for Async Loading
When suggestions load asynchronously, add a visually hidden div with aria-live="polite" and aria-atomic="true". Update its text content when loading completes: "5 results found" or "No results found". The screen reader announces this message after the current speech finishes, keeping users informed without interrupting them.
WAI-ARIA Authoring Practices Guide
The WAI-ARIA Authoring Practices Guide (APG) at w3.org/WAI/ARIA/apg contains a dedicated combobox pattern page with working code examples and detailed keyboard interaction specifications. Always refer to the APG when implementing interactive widgets like autocomplete, dialogs, or tabs to ensure full accessibility compliance.
aria-label and Placeholder
Provide an aria-label on the input if no visible label element exists: aria-label="Search suggestions". Do not rely solely on placeholder for labels — placeholders disappear when the user types and are not consistently announced by all screen readers. A visible label element with htmlFor is always the best option.
aria-activedescendant Purpose
What is the purpose of the aria-activedescendant attribute on an autocomplete input?
Lesson Recap: Accessibility for Autocomplete
Use role="combobox" on the wrapper, aria-autocomplete="list" on the input, aria-expanded, aria-controls, and aria-activedescendant to link the input and the suggestion list. Each option needs role="option", a unique id, and aria-selected. Add an aria-live region for async result counts.
Frequently asked questions
Is the “Accessibility for Autocomplete Widgets” lesson free?
Yes — the full text of “Accessibility for Autocomplete Widgets” is free to read here on the web, and the React Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the React Academy course, upgrade to CoddyKit PRO.
What will I learn in “Accessibility for Autocomplete Widgets”?
Apply aria-autocomplete, aria-expanded, role=listbox, and role=option to make the widget screen-reader friendly. You practise React Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start React Academy?
No prior experience is required. React Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Accessibility for Autocomplete Widgets” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this React Academy lesson?
Yes. Every React Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Controlled Input with Suggestion List
- Keyboard Navigation in Suggestion Lists
- Async Suggestions with Debounce
- Accessibility for Autocomplete Widgets