CodePark/ questions / ARIA in practice
START PRACTICINGPRACTICE
Frontend question · Accessibility › ARIA in practice

Which ARIA states do you use most in everyday UI (aria-expanded, aria-pressed, aria-current, aria-controls)? How do you keep them correct?

<button
  aria-expanded={open}
  aria-controls="filters-panel"
  onClick={() => setOpen(!open)}
>
  Filters
</button>
<div id="filters-panel" hidden={!open}>…</div>

These states tell screen reader users what sighted users see from the visuals.

The common ones:

  • aria-expanded: on a button that shows or hides something, like an accordion, a dropdown or a mobile menu. It is true when open. The screen reader says "Filters, button, expanded".
  • aria-pressed: on a toggle button, like a Bold button or Mute. It is true when on. Keep the label the same ("Mute"). Don't change both the label and the state, or users hear "Unmute, pressed" and can't tell what will happen.
  • aria-current="page": on the link to the page you are on, in navigation or breadcrumbs.
  • aria-controls: points to the id of the element the control changes. Screen reader support for it is weak, so treat it as a nice extra, not the main signal.

Keeping them correct: drive the attribute from the same state that drives the visuals. In React, aria-expanded={open} and hidden={!open} read the same open variable. Then they can never disagree. A stale aria-expanded="false" on an open menu is worse than no attribute at all.

  • aria-expanded tells users whether a disclosure, menu or accordion is open.
  • aria-pressed marks a toggle button as on or off, with a label that does not change.
  • aria-current="page" marks the current page in navigation.
  • aria-controls has weak screen reader support, so don't rely on it alone.
  • Drive ARIA states from the same state as the visuals so they never disagree.