Accessible Names Computation
How browsers compute accessible names from content, labels, aria-label, and labelledby — and how that powers Testing Library queries.
- accessibility
- accessible-names
Every interactive control needs an accessible name — the string assistive tech uses to announce it (“Button, Submit”). Browsers compute names from a priority of sources defined by the Accessible Name and Description Computation spec. If the name is wrong or empty, users and getByRole(..., { name }) both fail.
Docs: AccName, MDN Using ARIA.
Mental model (simplified priority)
For many controls, naming looks roughly like:
aria-labelledby(referenced elements’ text)aria-label- Associated
<label> value/ content (e.g. button text,alton img-in-button)title(last resort, inconsistent)
Exact algorithm is nuanced — when debugging, use the accessibility tree in DevTools.
Good patterns
<label for="q">Search</label>
<input id="q" type="search" />
<button type="submit">Create project</button>
<button type="button" aria-label="Close">
<svg aria-hidden="true">…</svg>
</button>
aria-labelledby composition
<h2 id="billing-title">Billing</h2>
<button type="button" aria-labelledby="billing-title edit-label">
<span id="edit-label">Edit</span>
</button>
<!-- Name ~ "Billing Edit" -->
Order of ids in aria-labelledby matters.
Description vs name
- Name — primary identity (
aria-label, label) - Description — extra help (
aria-describedby, sometimestitle)
<input id="pw" aria-describedby="pw-hint" />
<p id="pw-hint">At least 8 characters.</p>
SR may announce description after name/role.
Debugging
Chrome/Firefox/Safari: Accessibility pane shows computed Name / Role / Description. If name is empty, fix markup before writing a test id.
// Fails if button has no name
screen.getByRole('button', { name: /save/i });
Footguns
- Icon button with no
aria-label/ text. - Multiple labels competing.
aria-labeloverriding useful visible text unintentionally.- CSS
contentfor critical names (unreliable). - SVG without title/host name when meaningful.
Interview out-loud answer
“Accessible name is computed from labelledby, aria-label, native label, then content. I verify in the a11y tree and prefer visible labels. Testing Library name options use the same computation, so good names make tests and AT work together.”
Name from content examples
<a href="/docs">Documentation</a>
<!-- name: Documentation -->
<button type="button"><img src="trash.svg" alt="Delete" /></button>
<!-- name often from img alt when button has no other text -->
<button type="button"><img src="trash.svg" alt="" /> Delete</button>
<!-- name: Delete — decorative img alt empty -->
For buttons, visible text is the most robust name source. Nested image alt participates in name calculation and can surprise you when both alt and text exist.
Labelledby vs label string
aria-labelledby wins over aria-label in the computation when both are present. Prefer one clear mechanism. Debugging “wrong name”: remove extra ARIA until the tree shows the visible text you expect, then add only what’s missing.
Descriptions are not names
<button aria-describedby="tip">Export</button>
<p id="tip">Downloads a CSV of the current filters.</p>
SR may announce the description after the name — order varies. Don’t put the only critical identity in the description.
QA workflow
Open the Accessibility pane, read Name, assert with getByRole in tests, and spot-check design-system primitives once with VoiceOver or NVDA.
Platform differences
VoiceOver, NVDA, and TalkBack may announce the same tree node with slightly different wording. Optimize for correct roles, names, and states in the accessibility tree rather than chasing identical speech strings. If Chrome’s a11y pane shows the right name but one SR is quiet, check focus mode vs browse mode and whether the control is actually focused.
Related on this site
- ARIA labels and descriptions
- What is the accessibility tree
- Testing Library queries priority
- Accessible SVGs
- ARIA roles overview
Further reading
Related guides
- Accessible Combobox PatternBuild or evaluate comboboxes with APG keyboard behavior, aria-expanded/activedescendant, and filterable listbox pairing.
- Accessible Forms ErrorsLabel inputs, associate errors with fields, announce failures, and avoid placeholder-only forms that break accessibility.
- Accessible Menus PatternAPG menu and menubar keyboard model — arrow navigation, escape to close, aria-expanded, and when a disclosure is enough.
- Accessible Modals PatternsModal dialogs that work: focus trap, Escape, return focus, aria-modal, and why native dialog or APG patterns beat div soup.
- Accessible SVGsDecorative vs informative SVG icons — aria-hidden, title/desc, role=img, and pairing icons with accessible names on controls.