Search input has accessible label; autocomplete uses ARIA live region
Why it matters
A search input without an associated label fails WCAG 2.2 SC 4.1.2 (Name, Role, Value) — screen readers announce the field as "edit text" with no context, making it unusable for blind users. Autocomplete dropdowns that don't use aria-live or role="listbox" are invisible to assistive technology: suggestions appear visually but are never announced, so keyboard and screen reader users cannot benefit from them. WCAG 2.2 SC 4.1.3 (Status Messages) further requires that dynamic content changes like suggestion updates be communicated without requiring focus movement.
Severity rationale
Medium because the failure eliminates search usability for screen reader users while stopping short of a critical data or security exposure.
Remediation
Label the search input explicitly and annotate the suggestions container with ARIA roles. In components/SearchInput.tsx:
<label htmlFor="search-input">Search listings</label>
<input
id="search-input"
type="text"
role="combobox"
aria-expanded={suggestions.length > 0}
aria-autocomplete="list"
aria-controls="suggestions-list"
/>
{suggestions.length > 0 && (
<ul
id="suggestions-list"
role="listbox"
aria-live="polite"
>
{suggestions.map((s, i) => (
<li key={i} role="option">{s.name}</li>
))}
</ul>
)}
aria-live="polite" causes screen readers to announce new suggestions without interrupting the user's current context. Test with VoiceOver (macOS) or NVDA (Windows) to verify announcements fire on each suggestion update.
Detection
-
ID:
search-a11y -
Severity:
medium -
What to look for: Enumerate all relevant files and Inspect the search input. Check for an associated
<label>element oraria-label/aria-labelledbyon the input. For autocomplete suggestions, check whether there's anaria-live="polite"orrole="listbox"on the suggestions container so screen readers announce new suggestions. -
Pass criteria: At least 1 implementation must be present. Search input has a label (visible or via aria-label). Autocomplete suggestions container uses
aria-live="polite"orrole="combobox"+aria-expanded, allowing screen readers to announce new suggestions. -
Fail criteria: Search input has no label. Autocomplete suggestions are not announced to screen readers.
-
Skip (N/A) when: Search is not implemented. Signal: no search input found.
-
Detail on fail:
"Search input has no label or aria-label."or"Autocomplete dropdown has no aria-live. Screen readers won't announce suggestions." -
Remediation: Add accessibility attributes to search and autocomplete:
// components/SearchInput.tsx export function SearchInput({ onSuggestionSelect }) { const [suggestions, setSuggestions] = useState([]) return ( <div className="relative"> <label htmlFor="search-input">Search listings</label> <input id="search-input" type="text" onChange={e => handleSearchChange(e.target.value)} aria-describedby="suggestions-list" role="combobox" aria-expanded={suggestions.length > 0} aria-autocomplete="list" /> {suggestions.length > 0 && ( <ul id="suggestions-list" role="listbox" aria-live="polite" className="absolute top-full left-0 right-0 bg-white border" > {suggestions.map((s, i) => ( <li key={i} role="option" onClick={() => onSuggestionSelect(s)}> {s.name} </li> ))} </ul> )} </div> ) }
External references
- wcag:2.2 · 1.3.1 — Info and Relationships
- wcag:2.2 · 4.1.3 — Status Messages
- wcag:2.2 · 4.1.2 — Name, Role, Value
Taxons
History
- 2026-04-18·v1.0.0·Initial import from directory-search-discovery·automated