Aria-Label is Not Always the Answer

Reading time: about 4 minutes


Aria-Label is not Always the Answer with an illustration of woman standing and looking at a screen with rectangles representing text, and lines going from the texts to outside the screen to another lines annotating aria-labels.

Listen to this blog post, read by Eevis:

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:

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:

Landmark-roles with HTML-elements having 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:

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

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.

If you liked the post, you can tweet about it or comment on or Twitter.