Accessible names are computed from multiple sources in a fixed, overridable order
Aliases: AccName · aria-labelledby · aria-label · computed name
What it is
The name a piece of assistive technology speaks for a control is not a nickname for “whatever is written on screen.” It is computed by the AccName algorithm: accessible name computation. Priority is roughly the text of nodes referenced by aria-labelledby, then aria-label, then host-language slots (<label>, a button’s contents, alt, an input’s value, and so on), and only then title. The first source that yields a non-empty result wins; everything after it is ignored. One higher-priority attribute from the author overrides the words the user is looking at.
Why it happens
The computation is an ordered fold, not a concatenation. aria-labelledby pulls text from nodes in ID order and may point at nodes that are not visible. aria-label is an author string that replaces the words inside a button rather than adding to them. Native slots stay in their lanes: checkboxes via an associated label, images via alt, links via descendant text. title is the floor, and many readers treat it as a description rather than a name.
The second layer is what “overridable” means in engineering. The priority table puts author attributes and visible text on the same track, author first. Renaming therefore need not touch the interface: an aria-label gives speech, automation, and voice control a different string. That escape hatch is intentional, and it is the easiest place to rewrite what the user sees without noticing. Role and state are spoken after the name is already computed — the algorithm itself does not ask whether the three line up.
Studying it
Read Computed Name in the developer tools accessibility pane; do not take one spoken pass as the result. Build a minimal set: visible text only; plus aria-label; plus aria-labelledby pointing at hidden text; title only. Hear the name string on NVDA+Firefox, JAWS+Chrome, and VoiceOver+Safari, and note agreement with the pane.
Independent variables: combination of name sources, empty-string values, multiple IDs. Dependent variables: computed name, spoken name, whether fallback to the next source occurred.
Whether an empty aria-label="" blocks fallback differs across engines. Record the fork; it is not a rounding error.
Where it stops holding
SVG, MathML, table headers, and the default “Submit” on input type="submit" have host-specific rules; button priority is not a universal theorem. aria-labelledby recurses into the name sources of referenced nodes; cycles are cut, and the result can be shorter than the author expected. Whether hidden nodes participate depends on the hiding method: display:none and aria-hidden are excluded at different steps. Mobile readers sometimes speak both the visible text and the computed name, which sounds like “no override” and is actually a verbosity policy.
Applying it
- Pick one highest name source and write it correctly; do not stack
aria-label,labelledby, and visible text hoping they will add. - When visible text must be overridden (icon-only buttons, overlong labels, concatenated phrases), use
aria-labelledbyoraria-labelexplicitly and confirm the computed name in the inspector. - Do not leave an empty
aria-labelor alabelledbypointing at a deleted node as a placeholder; it may block fallback to visible text. - How to check: open the accessibility pane on every interactive node and read Computed Name; then listen in NVDA to the name only (no description). If the pane, the speech, and the source the author thought they were using disagree, priority was mis-set or truncated by an empty value.
Related
- Same group: J5.10.2 Visible text and the computed accessible name can disagree · J5.10.3 State changes must be written to the accessibility tree, not only to appearance · J5.10.4 Custom widgets often ship a role but omit the matching state properties
- Nearby: J5.02 Accessibility tree and roles · J5.04 Voice control
- Search terms:
accessible name computation·aria-labelledby·AccName