Okay, you've learned about accessibility and that there is sometimes a need to make, for example, the link text more descriptive for screen reader users. You've learned about the aria-label
-attribute, and its powers. It's the answer to everything!
I'm afraid I have to say that it is not. It doesn't work with all HTML elements. In this blog post, I'll dig a bit deeper into the aria-label
-attribute, and its usage and limitations, and options.
What Is aria-label
?
So, let's first talk about the specification and where to use it. W3C Recommendation for Accessible Rich Internet Applications (WAI-ARIA)-document defines aria-label
as "a string value that labels the current element." You can use it to provide a recognizable name of the object if there is no visible text on the screen that could be used as the label. If there was, aria-labelledby
should be used.
The most important thing, and the reason I'm writing this article, is that developers should use it only with the following elements:
- interactive elements (such as links, buttons, inputs et cetera)
- Elements that have a landmark role
- Elements that have an ARIA-widget role
-
img
oriframe
-elements
Source: Short note about aria-label,
aria-labelledby
and aria-describedby
by Léonie Watson.
aria-label
on these elements works consistently with assistive technologies. The support is inconsistent if you use it with any other tag, such as div
or span.
More about that in Aria-label and non-supported elements.
Let's look into each one of these elements a bit more.
Interactive Elements
Interactive elements are tags intended for user interaction. It means, for example, button
, a
(when href
-attribute is present), input
, details
and others. The main idea is that users can interact with them.
Elements with Landmark Role
Elements can have landmark roles either implicitly or explicitly. Having an implicit role means that some of the HTML elements have roles set to them natively. The explicit role, on the other hand, is set with role
-attribute.
I'll list the different roles and elements that already have those roles:
Role | HTML-element |
---|---|
banner | (document) <header>
|
complementary | <aside> |
contentinfo | (document) <footer>
|
form | <form> (if provided an accessible name via aria-label or aria-labelledby ) |
main | <main> |
navigation | <nav> |
region | <section> |
Source: MDN's list of landmark roles
In addition to the roles listed, there's a search
-role, which is only an explicit role, so, set with role
-attribute.
Elements with ARIA-widget Role
ARIA-widget roles define typical interactive patterns. These patterns usually need JavaScript to implement their intended behavior. There are multiple ARIA-widget roles, and I'm going to list a couple of them:
tab
tablist
searchbox
treeitem
switch
You can find more from MDN's list of ARIA-widget roles.
img
and iframe
Image and iframe are two elements where aria-label
works as well. For img,
there are rare cases when you might need aria-label.
In general, you should use the alt
-attribute to provide an accessible name for the image.
How does aria-label
work?
aria-label
overrides the visible text in elements, where the accessible name would come from the child element. For example:
<button aria-label="Something else">
click me
</button>
The above button would be exposed as "Something else" to screen reader users.
aria-label
and non-supported elements
So, as mentioned, the support for aria-label
is inconsistent with, for example, div
and span.
If the div
or span
doesn't have any role, aria-label
is ignored. The same goes for other non-interactive elements, such as p,
ul,
li,
or legend
as well.
If they have a landmark role, support is still inconsistent. Per Notes on ARIA Use in HTML, some widget roles work better than others:
Its fine to use aria-label or aria-labelledby on div elements with role=navigation, role=search, role=main, JAWS doesn't support them on role=banner, role=complementary, role=contentinfo. NVDA, VoiceOver, and Talkback are OK.
Options for aria-label
If aria-label
is not the answer, then what is? Well, it depends. In general, I would recommend adding visible text. Usually, when you're adding text for screen-reader users, it would be helpful for sighted users as well.
However, if a non-visible text is needed, you could add visually hidden text with CSS. You can read more and find a CSS-snippet from The A11Y Project's article Hide Content.
Wrapping Up
aria-label
is a helpful tool in cases when you need to add an accessible name for an element, and there is no already visible text to be used. However, you can't use it with every HTML tag. In general, those tags that don't work are non-interactive elements.
There are exceptions: If, for example, div
has one of the roles listed above, then screen readers read it. But there are inconsistencies with some roles: for example, roles banner
, complementary,
and contentinfo
are something that JAWS ignores, while VoiceOver, TalkBack, and NVDA support them.
I listed two options for cases when aria-label
doesn't work. You could add a visible text, as it usually would be helpful for all users. Another option is to add visually hidden text.