- Success Criterion 4.1.2
- Conformance level A
Expanded State Attribute That Never Updates When Toggled
4.1.2 — Name, Role, Value
Scenario
Setting
A fitness app's workout tracker
What’s wrong
aria-expanded (the open/closed state in code) present but never updated by JS (state stuck).
Example
<button aria-expanded="false" onclick="toggleDetails('squat')">Squat: 3 sets</button>
<div id="squat-details" class="details open">45 lb, 12 reps, rest 60s</div>
<!-- clicking the button adds the "open" class and shows the div,
but the script never touches aria-expanded --> Why it matters
A screen reader user who opens the squat details still hears "collapsed" and may click again, hiding what they just opened.
How to test
Toggle a stateful control (expand, select, check) and watch DevTools live: if the state attribute doesn't change value, it fails.
How to fix
Update aria-expanded in the exact same function that toggles the visual "open" class.
function toggleDetails(id) {
const btn = document.querySelector(`[data-target="${id}"]`);
const isOpen = btn.getAttribute('aria-expanded') === 'true';
btn.setAttribute('aria-expanded', String(!isOpen));
document.getElementById(`${id}-details`).classList.toggle('open');
} Outcome
A lifter opens the squat card and hears "expanded" confirming the sets are now visible.
Who is affected
Screen reader users tracking sets cannot trust the expand or collapse state of any exercise card.
Learn more
- Understanding Understanding document (opens in a new tab)
Related scenarios
- Custom Dropdown or Slider With No Accessibility API Support
- 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