Name controls from visible text with aria-labelledby
aria-labelledby names a control by pointing at text already on the page, using the id of the element holding it. W3C lists it as sufficient for both 1.3.1 Info and Relationships and 4.1.2 Name, Role, Value, unqualified in each case. The attribute takes more than one id, separated by spaces. That is the whole point of it. A row of Add to cart buttons becomes 10 distinct controls once each one points at its own product title and at itself. That is how a sighted reader tells them apart in the first place, by reading the card around the button. Because the name is assembled from visible text it cannot drift away from what the page says, which is the failure mode a hand-typed name has. Three differences from a plain label element are worth knowing before you swap one for the other. It can point at several elements, and it works on things that are not form controls. What it does not bring is the click-the-label-to-focus-the-field behavior a label element gives you, and that is a real loss for anyone with limited hand control. W3C's answer there is to keep the label, or rebuild that behavior in script.
How we find it in an audit
Repeated controls are where we look first, because a category page with 10 identical announcements is a finding no scanner will raise. We read the announced name for every button in a repeating component and check it tells one card from the next. Then we test the ids themselves, since an id that stops resolving after a component gets renamed is dropped in silence and the control quietly loses its name. Nothing on screen changes when that happens, which is how it survives release after release.
How affected users experience it
In the buttons list a screen reader user navigates by, 10 entries reading add to cart are 10 identical doors. Add which one? The listener has to leave the list, walk back into the page, and read around each button to work out which product it belongs to, for every product on the page. Names built from the product titles turn that list into add to cart, gold twist ring, and the page becomes usable at the speed a sighted visitor scans it. Voice control users get the same win, because now there is something specific to say.
Passes vs. fails
Passes
<h3 id="p7">Gold twist ring</h3>
<button id="add7" aria-labelledby="p7 add7">Add to cart</button>
<h3 id="p8">Silver band</h3>
<button id="add8" aria-labelledby="p8 add8">Add to cart</button>Fails
<h3>Gold twist ring</h3>
<button>Add to cart</button>
<h3>Silver band</h3>
<button>Add to cart</button>How this gets tested
The W3C publishes test rules that define what a checker looks for here.
- Image button has non-empty accessible nameA tool can check this
- Link has non-empty accessible nameA tool can check this
- ARIA attribute is defined in WAI-ARIAA tool can check this
- ARIA state or property has valid valueA tool can check this
- Element with role attribute has required states and propertiesA tool can check this
- Form field has non-empty accessible nameA tool can check this
- Role attribute has valid valueA tool can check this
- ARIA state or property is permittedA tool can check this
- Button has non-empty accessible nameA tool can check this
- Element with aria-hidden has no content in sequential focus navigationA tool can check this
- Element with presentational children has no focusable contentA tool can check this
- Menuitem has non-empty accessible nameA tool can check this
- Summary element has non-empty accessible nameA tool can check this
- Iframe element has non-empty accessible nameA tool can check this
- Iframe elements with identical accessible names have equivalent purposeA tool finds candidates, you decide
- Headers attribute specified on a cell refers to cells in the same table elementA tool can check this
- ARIA global properties not used where prohibitedA tool can check this
- ARIA required context roleA tool can check this
- ARIA required owned elementsA tool can check this
- Table header cell has assigned cellsA tool can check this
Other ways to satisfy this rule
23 guides on this site are filed under 4.1.2 Name, Role, Value. W3C lists this one as sufficient for that rule on its own. Implement it correctly, in a way your readers' software actually supports, and the rule is met.
- ARIA4sufficientGive custom widgets a real ARIA role
- ARIA5sufficientExpose widget state with ARIA attributes
- ARIA14sufficientLabel icon-only controls with aria-label
- G10sufficientBuild custom components on accessibility-supported tech
- G108sufficientExpose name, role, and changes through markup
- G135sufficientExpose controls through the platform accessibility API
This guide is our interpretation of W3C technique ARIA16: Using aria-labelledby to provide a name for user interface controls. W3C publishes its techniques as guidance rather than as the standard, and says so on every one of them. The success criterion is what conformance is measured against, and a technique is one documented way to meet it.