Accessibility
a11y/state-exposed
Custom toggles, disclosures and selections expose their state (aria-expanded, aria-pressed, aria-checked, aria-selected).
seriousmanualWCAG 4.1.2 · Afe-a11y-aria
Why
When only a CSS class shows that a menu is open or a filter is on, a screen reader user hears the same "button" before and after the click and cannot tell what happened.
Fix
Bind the state attribute to the same variable that drives the class: aria-expanded on a button that shows and hides content, aria-pressed on a toggle button whose label stays the same, aria-checked on role="switch", aria-selected on tabs and options, aria-current="page" on the current navigation link. Prefer native state (<details open>, <input type="checkbox">) when it fits.
Examples
// bad: the state lives only in the class
<button className={open ? 'is-open' : ''} onClick={toggle}>Filters</button>
// good
<button aria-expanded={open} aria-controls="filters" onClick={toggle}>Filters</button>Sources
Facts
- Id
a11y/state-exposed- Severity
- serious
- Check
- manual a person reviews it; the report lists it as a checklist
- Applies to
htmlangularvuesvelteastrojsx- WCAG 2.2
- 4.1.2, level A
- Taught by the skill
fe-a11y-ariaARIA, names and live regions- Since version
- 0.1.0
Read it in the terminal
npx github:dawidolko/frontend-skills explain a11y/state-exposed