Without name, role, and state, assistive technology cannot express a control
Aliases: accessible name · role · state · Name Role Value · accessibility tree fields
What it is
Assistive technology does not read pixels. It queries three slots on each interactive node in the accessibility tree: accessible name, role, and state (or value). Name is what to call the thing, role is what kind of control it is, state is which condition it is in now. The three compose one utterance that can be spoken, collected by a rotor, and inspected as on or off. Leave any slot empty and the utterance breaks: a nameless "button", a named object that never appears in the control list, or a control you can find but cannot tell is expanded.
The question is whether this node can be said completely, not whether the markup should have been native, and not whether DOM order is correct. Looking like a button does not fill the three slots.
Why it happens
Screen readers and voice control talk to the platform accessibility API, not the render tree. The API computes a name from a priority chain (label, aria-labelledby, aria-label, contents, title), then attaches role and the current state. Break the chain and the name is empty: an icon-only button, an input whose visible caption is not associated with for or wrapping. Role that does not match behaviour — a clickable node exposed as an unrole'd group — keeps the object out of rotors, touch exploration, and voice commands. State that is never exposed (pressed, expanded, selected, disabled, current value) lets the user hear that a control exists, not that it changed.
The three slots are fields of one expression, not optional extras. Name answers "what is it called", role answers "what is it for", state answers "how is it now". Filling only the name is a business card that never says whether the door is open.
Where it stops holding
Static, non-interactive text has no interactive state to report; name plus role (or being ordinary document text) is enough — do not invent aria-pressed. For progress and sliders the "state" is a value, not a boolean; an empty value is worse than a wrong one. Name computation differs by engine: desktop VoiceOver and mobile TalkBack do not share every priority, so a pass on one engine does not transfer. Decorative graphics should not enter the tree at all; naming them is noise, which is a question of exposure, not of a missing slot.
Applying it
- For every interactive control, list the three slots: how the visible caption becomes the accessible name, whether role matches behaviour, and which property carries pressed / expanded / selected / disabled / value.
- Icon buttons, unlabeled switches, and custom options need an associated label or
aria-label. When a visible label exists, associate it; do not overlay a differently wordedaria-label. - Toggles, accordions, options, and progress must expose state or value on the accessibility tree; colour or icon swaps are not enough.
- How to check: in an accessibility-tree inspector, confirm name, role, and state are non-empty and match the visual UI. Then walk the main path with one screen reader and confirm the rotor collects by role and that toggling is announced as state change.