Don't Use aria-label on Static Text Elements (2024)

birdculture1 pts0 comments

Don’t Use aria-label on Static Text Elements | Ben Myers

Links

Settings

Theme<br>Light<br>Dark<br>System

Animations<br>On<br>Off<br>System

Scrolling<br>Smooth<br>Instant

Skip to Content

Too Long; Didn’t Read

Don’t use the aria-label or aria-labelledby attributes on s, s, or other elements representing static/noninteractive text-level semantics, such as , , , and so forth, unless those elements’ roles have been overridden with roles that expect accessible names.

That’s a bit of a mouthful, and I couldn’t fit it all in the title.

The Antipattern

A very common accessibility bug involves applying the aria-label or aria-labelledby attributes to static, text-level semantics, especially s and s.

Copy code

span aria-label="Vegetarian"><br>🌱<br>span>

div aria-labelledby="about"><br>h2 id="about"><br>About<br>h2><br>div>

div tabindex="-1" aria-label="Draggable item. Click, tap, or press Space to select. Drag, or use arrow keys to move.">

div>

However, aria-label and aria-labelledby aren’t permitted on these elements — at least, not without also changing those elements’ roles. This means that in most browser/screenreader combinations (we’ll get to a notable exception shortly), users generally won’t receive invalidly applied aria-labels or aria-labelledbys, making these accessibility “fixes” anything but.

The short, rule-of-thumb-friendly explanation here is that aria-label and aria-labelledby are generally intended for interactive elements (buttons, links, form controls) and landmark regions.

The longer, more precise explanation is that HTML elements are mapped to roles, which specify which kind of thing the element represents. Certain ARIA attributes are only permitted on certain roles. aria-label and aria-labelledby replace an element’s accessible name, which only some roles are permitted to have in the first place. The way aria-label and aria-labelledby are defined in the ARIA 1.2 spec, they are permitted on any role except the following: caption, code, deletion, emphasis, generic, insertion, paragraph, presentation, strong, subscript, and superscript — generally, your static, noninteractive, text-level semantics. At time of writing, the ARIA 1.3 draft spec, which browsers have taken a headstart in supporting, also prohibits aria-label and aria-labelledby on the definition, mark, none, suggestion, term, and time roles. This means that, per the specs, the following elements aren’t allowed an aria-label or aria-labelledby out of the box, until you start overriding roles:

Here there be chonky tables

The following tables were assembled by crossreferencing the ARIA 1.2 spec and ARIA 1.3 draft spec with the HTML Accessibility API Mappings 1.0 draft spec. These tables almost certainly aren’t perfect, but should hopefully be complete enough for most scenarios.

Roles Prohibited from aria-label or aria-labelledby in ARIA 1.2

Role<br>HTML Elements with Default Role

caption

code

deletion

emphasis

generic

Custom elements

without an href

without an href

(when scoped to or other sectioning content)

(when scoped to or other sectioning content)

insertion

paragraph

presentation

None.

strong

subscript

superscript

Roles Newly Prohibited from aria-label or aria-labelledby in ARIA 1.3 Draft

Role<br>HTML Elements with Default Role

definition

mark

none

None.

suggestion

None.

term

time

This matters because browsers adhere to these specs when assembling accessibility trees for screenreaders to consume, and screenreaders are generally built around supporting these specs. It’s less that aria-label doesn’t “work” on static, text-level semantics, but that it’s not even intended to.[note 1]

If a browser/screenreader combination does handle aria-label and aria-labelledby on static elements like it does permitted roles, that’s an exception to the rule. Which brings us to a common source of confusion:

But VoiceOver…

It’s important to test changes with actual assistive technologies like screenreaders, but this can cause a footgun of its own if we test just one tool and assume that its behavior is representative of all similar tools.

We can see a solid example of this with the VoiceOver screenreader built into macOS. When it comes to aria-labels on generic elements, VoiceOver generally does announce the contents of the aria-label. If that’s the behavior you were expecting, then testing with VoiceOver alone would seem to suggest that this is a condoned, functioning pattern. In actuality, VoiceOver is doing what many user agents do in the face of invalid code: compensating for developers’ misguided intent so as to not penalize users. That aria-label “works” on generic elements in VoiceOver is a nonstandard remediation of noncompliant code, not an endorsement of a technique working as intended.

As WebAIM’s surveys of screenreader users have borne out, VoiceOver for macOS is severely overrepresented by developers and site/app testers compared to disabled day-to-day screenreader users.[note 2] When relying on solely VoiceOver for macOS when...

aria label elements labelledby roles voiceover

Related Articles