- Success Criterion 4.1.2
- Conformance level A
- W3C reference F15
Custom Dropdown or Slider With No Accessibility API Support
4.1.2 — Name, Role, Value
Scenario
Setting
A food delivery app's restaurant menu
What’s wrong
A custom-built control (dropdown, slider, dialog) doesn't tell assistive technology what it is or what state it's in, because it skips the standard accessibility hooks.
Example
<div class="sort-dropdown" onclick="toggleSort()">
<div class="selected">Sort: Rating</div>
<div class="options" id="sortOptions">
<div onclick="setSort('rating')">Rating</div>
<div onclick="setSort('delivery')">Delivery time</div>
</div>
</div>
<!-- no role, no tabindex, no keyboard handling --> Why it matters
A diner using a screen reader cannot tell this is a dropdown, so they cannot resort the restaurant list by delivery time.
How to test
Inspect the custom control in DevTools' Accessibility panel: if it doesn't expose a name, role, or state through the accessibility API, it fails.
How to fix
Prefer a native select element unless the visual design truly needs a custom listbox.
<button aria-haspopup="listbox" aria-expanded="false" id="sortBtn">Sort: Rating</button>
<ul role="listbox" aria-labelledby="sortBtn" hidden>
<li role="option" aria-selected="true">Rating</li>
<li role="option" aria-selected="false">Delivery time</li>
</ul> Outcome
A hungry customer resorts the menu by delivery time using only the keyboard.
Who is affected
Screen reader and switch-access users browsing restaurants cannot discover or operate the sort control.
Learn more
- Understanding Understanding document (opens in a new tab)
- Technique Related technique (opens in a new tab)
Related scenarios
- Content Changes That Never Update Their Accessible Name
- Scripted Link or Button With No Real Role or Keyboard Support
- Clickable Div Turned Into a Control but Given No ARIA Role
- Form Field With No Programmatic Label at All
- Assistive Technology Never Told Which Element Currently Has Focus
- Multi-Part Field Where Each Box Has No Individual Name