In plain English
Assistive technologies do not see your buttons and menus, they read the code behind them. For each control, they need three facts: its role (is this a button, a checkbox, a tab?), its name (what is it called?), and its value or state (is it checked, expanded, selected?). If any of those is missing, a screen reader either says nothing or says the wrong thing, and the control becomes unusable.
This is the criterion that custom, JavaScript-built widgets fail most, because a
<div> styled to look like a button has no role, no name, and no state unless
you add them.
Who this is for
- Screen-reader users, who rely entirely on the exposed name, role, and state to understand and operate controls.
- Users of other assistive tech (voice control, switch access), which also depend on these programmatic properties.
What “good” looks like
Use native elements, or add the full ARIA picture to custom ones.
<!-- Good: native, exposes name + role + state automatically -->
<button aria-pressed="true">Add to wishlist</button>
<!-- Good: custom widget with role, name, and state -->
<div role="checkbox" aria-checked="false" tabindex="0"
aria-labelledby="terms-label">…</div>
<span id="terms-label">I agree to the terms</span>
<!-- Bad: a div that looks like a control but exposes nothing -->
<div class="checkbox"></div>
Where stores get it wrong
Custom dropdowns, toggles, tabs, and star-rating widgets built from bare
<div>s with no role or name, and toggle buttons that never update their state.
Automated scanners catch only some of this, which is
why manual review matters.
These are frequent entries on the
common failures list.