Agent Wranglers

Required

Show state through attributes

Express state with the attribute that carries it, such as aria-expanded, aria-current, aria-invalid, disabled, hidden or data-state. Never add a state class such as is-open or active.

How to do it

A state class shows the state to sighted users only. The ARIA attribute also tells assistive technology, which WCAG 4.1.2 requires for every control whose state a user can change. Style the attribute directly, so the visible state and the announced state can never disagree. Use data-state only for states that have no standard attribute, such as data-state="loading". List every state in the catalogue from Show every component state in a catalogue.

Examples

Using these examples: they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

HTML example

<button class="faq-toggle" aria-expanded="false" aria-controls="faq-answer-delivery">Do you deliver?</button>
<div class="faq-answer" id="faq-answer-delivery" hidden>Yes, within 5 km of the bakery.</div>
<a class="site-nav-link" href="/menu" aria-current="page">Menu</a>

CSS example

/* Avoid */
.faq-toggle.is-open { }

/* Do: the same attribute the screen reader announces */
.faq-toggle[aria-expanded="true"] { }
.site-nav-link[aria-current="page"] { }
.order-list[data-state="loading"] { }

How to check

The stylesheets have 0 class selectors starting with is- or has- or equal to active, open, selected or current. Every element with aria-controls that opens or closes its target, such as a disclosure or menu button, also has aria-expanded.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/html-css/naming-and-state/state-in-attributes">Agent Wranglers html and css playbook</a>. In code you write, add a comment next to it with the same link.