ARIA property
aria-label
Gives an element a name as a plain string. Use it when there is no visible text to point at.
It gives the element a name, and it wins over most of the other ways a name could have been worked out. That is the part that surprises people. Put it on a control that already has visible text and the visible text stops being the name.
Which roles may carry aria-label
- Value
- string
- Filed as
- A property, which is how ARIA files it and not a rule about how often it changes.
- Roles that may carry it
- Any role. This one is global, which is why no individual role lists it.
Those 12 roles have no name of their own, and ARIA does not merely say that naming them is pointless. It says authors must not do it, which makes it an authoring error rather than harmless extra markup. The one that catches people is generic, because a bare div or span maps to it.
Global means no role has to grant permission for it. There is one more place to check, because ARIA in HTML sets rules per element as well as per role, and it allows no aria-* attributes at all on a datalist or on the html element. Past that, the way a global attribute goes wrong is rarely where it sits. It is whether it is still true, which is the next section.
Every role above comes from the specification's own list for this attribute, checked name for name. The normative definition stays with the W3C, in the aria-label section of the ARIA specification.
Keeping aria-label true
The failure to watch for is the silent override. A button reading Send that carries an aria-label of Submit form now has a name nobody can see, so somebody using voice control who says click Send is naming something that no longer exists. Where you need to add words to a control that has visible text, aria-describedby is the attribute for it. The spec's own preference runs the same way. If the label text is already in the page, use aria-labelledby and point at it, and keep aria-label for the case where there genuinely is no visible label to point at. One last trap. An empty aria-label is treated as if the attribute were not there at all, so it does not clear a name, it just fails to set one. The whole order a name gets worked out in is set out in how accessible names are computed.
How aria-label gets checked
There are test rules that check an ARIA attribute is one that exists, is allowed on the role underneath it, and carries a value of the right type. What they map to is ARIA's own author requirements rather than any WCAG criterion, so a misplaced attribute breaks ARIA without being a WCAG failure by itself. It becomes one under 4.1.2 Name, Role, Value the moment the missing or wrong value means the control's state cannot be worked out programmatically, which is what usually happens next.
Nothing automated catches the failure this page is about. A stale value is a valid value, on a permitted role, with the right type. It is only wrong about the world.
Attributes you will meet alongside aria-label
- aria-atomic Whether an update should be read whole, or only the part that changed.
- aria-busy Says a region is still being updated, so wait before announcing it.
- aria-controls Points at what this control operates. A combobox has to say what it opens.
- aria-current Marks the one item in a set that represents the here and now, such as the current page in a nav.
- aria-describedby Points at further description, read after the name. Hints and error text usually go here.
- aria-details Points at richer explanation elsewhere in the page, which people can navigate to rather than have read out.
- aria-flowto Overrides reading order by pointing at what should be read next. Rarely the right answer.
- aria-hidden Removes an element from the accessibility tree while leaving it on screen.
Every ARIA state and property · Every ARIA role · ARIA explained