Meaningful labels using ARIA – or not.

by Suzy Naschansky published on

If I had a dollar for every time I've had to tell someone to remove an aria-label from an interactive control that has actual visible text, I could have bought Twitter! As a former developer and current accessibility consultant, it is my sincere hope that by reading this article, developers unfamiliar with or unsure about this topic will have a better understanding of the differences between aria-label, aria-labelledby, and aria-describedby.

Semantic HTML elements convey meaning - role and state - to browsers and assistive technologies. Whenever you can use an appropriate native HTML element, you should do so. For example, using a <button>, instead of using a generic element such as a <div> and then adding ARIA roles and states and properties and JavaScript functions and CSS to make it look and behave like a button, is a much better way to code. In fact, the First Rule of ARIA is: Use HTML. (Credit for that paraphrase.)

When should I use ARIA to label something?

Using this priority of methods for labelling a control list, first ask yourself, “do I really need to use ARIA here?” That is, can you add visible text to your element or programmatically associate existing text using native HTML semantics? There are multiple ways to do this; here are a few.

HTML <label> tag

Use the for attribute to tie a <label> to its input.

<label for="fname">First name:</label>  
<input type="text" id="fname">

<label for="lname">Last name:</label>
<input type="text" id="lname">

HTML <fieldset> and <legend> tags

Use <fieldset> and <legend> tags to group and label radio button and checkbox sets.

<fieldset>  
<legend>What is your favorite breakfast food?</legend>

<input type="radio" id="waffles" name="fav_breakfast" value="waffles">
<label for="waffles">Waffles</label>

<input type="radio" id="pancakes" name="fav_breakfast" value="pancakes">
<label for="pancakes">Pancakes</label>

<input type="radio" id="leftover_pizza" name="fav_breakfast" value="leftover_pizza">
<label for="pizza">Leftover Pizza</label>
</fieldset>

HTML alt attribute for images

Use meaningful alt text for images, particularly when the image is the only content for a link or a button. The alt text in the next example is much more meaningful to a screen reader user for understanding the purpose of the link than simply describing the bags of money in the image would be.

<a href="/win-the-lottery">  
<img src="bags-of-money.png" alt="How to win the lottery. Heaping bags of money to help prove the point.">
</a>

ARIA should be used only to enhance HTML when necessary, not to "fix" bad HTML. That being said, there are times when it may be necessary to clarify or supplement labeling for various elements in order to make them more accessible for users of assistive technologies such as screen reading or voice control software.

There are some great tips on creating effective and user-friendly names in the tutorial better accessible names that apply to all methods of labeling.

Should I use aria-label or aria-labelledby?

TLDR:

  • If text for the label is available somewhere on the page, use aria-labelledby.
  • If text for the label doesn't exist on the page, use aria-label.

The aria-label attribute accepts a string of text as its value. The aria-labelledby attribute takes the value of one or more id attributes. It's especially important to understand that both aria-label and aria-labelledby replace any existing label content for assistive technologies. Let's go over some examples.

Appropriate uses of aria-label

Interactive elements with informative icons or icon fonts that don't have accompanying text all need textual names to be accessible. Some examples are links to social media pages and icon-only buttons such as Print, Download, or Info. The aria-label attribute works great for these situations. Here, an icon is displayed using CSS for an otherwise empty link:

<a href="..." class="icon-facebook social-icon" aria-label="Facebook page"></a>

You know that "X" button in the corner of a modal? Please, give it an aria-label! The following example will overwrite the visible text content of "X" and announce as "Close," which definitely makes more sense than hearing "X".

<button aria-label="Close">X</button>

In some cases you could instead provide alt text that would create an appropriate button or link label (and get bonus points for following ARIA Rule #1!).

<button>
<img src="system-icon-circle-x.png" alt="Close">
</button>

When there are multiple navigation areas on a page, adding an aria-label to each can help a screen reader user differentiate between the regions and better understand where they are on the page. Don't include the word "navigation" as that is already announced via the <nav> role.

<nav aria-label="Primary"> ... </nav>  
<nav aria-label="Breadcrumbs"> ... </nav>
<div role="navigation" aria-label="Footer"> ... </div>`

Make sure your aria-label value is meaningful. In this next example, the info button label essentially just describes the button's icon:

<!-- don't do this -->  
<p>This makes me want to absquatulate.
<button aria-label="question mark">
<i class="fa fa-question-circle"></i>
</button>
</p>

A much better solution would be to provide relevant content about what the info button does or why it's here:

<p>This makes me want to absquatulate.  
<button aria-label="What does absquatulate mean?">
<i class="fa fa-question-circle"></i>
</button>
</p>

Appropriate uses of aria-labelledby

When suitable text for a label already exists elsewhere on the page, aria-labelledby is the preferred method for labeling (if you must use ARIA). Multiple id values from other elements are separated by a space within the aria-labelledby's value to concatenate a single string of text.

Suppose you have a series of news articles on a page, and each article has a link that says "Read more." You can use aria-labelledby to add more context in order to differentiate between these generic links. Since aria-labelledby will overwrite the visible text content of the link, you'll need to add the "Read more" text back in as well.

<h2 id="article1-heading">All About Dragons</h2>  
<p>I like dragons. Blah blah blah blah blah.</p>
<p>
<a id="article1-read-more" aria-labelledby="article1-read-more article1-heading">Read more</a>
</p>

This will result in the link being announced as "Read more All About Dragons." You could go one step better and rewrite those "Read more" links to be more descriptive for everyone.

When should I skip ARIA for labeling?

As has been noted by Léonie Watson, Steve Faulkner, Eevis and many others, these attributes do not work on every element. These labeling attributes are intended for:

  • interactive elements
  • structural elements with landmark roles
  • widgets with explicit roles

Check out this handy chart of ARIA roles and their requirements for naming.

Adding an aria-label will overwrite any visible text label that already exists, and adding an aria-labelledby will overwrite any visible text AND any aria-label provided. In general, you don't want to add aria-label when an appropriate visible text label already exists.

<a href="about/" aria-label="About Us">About Us</a>

At first glance, this may seem harmless and it won't throw an error in automated or likely even manual accessibility testing, but what about when your company goes international? You're setting your future-self up for extra work and more headaches when that redundant non-visible label doesn't get translated or updated.

<a href="about/" aria-label="About Us">Sobre Nosotros</a>

Never, ever do this:

<button id="run-button-1" aria-label="Customize Report">Run Report</button>

Sighted users will see the button's visible text label of "Run Report", but screen reader users will hear the button's accessible name of "Customize Report". Presumably "Run" and "Customize" are two different actions!

The problem in the previous example is not limited to screen reader users. Someone using voice control software might say "Run Report" to activate the control, but nothing will happen since that's not the accessible name. Voice control users will have to find a workaround when they need to perform the "Run" action that this button visibly indicates.

The following examples show some additional inappropriate uses of aria-label; you may as well save yourself some coding keystrokes and time spent debugging, by not doing any of the following bad examples.

Non-interactive elements

<div aria-label="Product Group">...</div>

Don't put aria-label on a <div> or other non-interactive element without an explicit role; it does nothing but create tech debt.

Decorative images

<img src="decorative-image.jpg" aria-label="">

An empty aria-label attribute is not the same as an empty alt attribute. Use an empty alt attribute (alt="") for decorative images.

Prohibited roles

<p aria-label="Causes of eye twitching"> ... </p>

HTML elements whose implicit roles prohibit the use of aria-label or aria-labelledby are listed in the current WAI-ARIA specifications.

What about aria-describedby?

According to the WAI-ARIA specification for aria-describedby, "a label should be concise, where a description is intended to provide more verbose information." Any aria-describedby content is announced by screen reading software after the element's label is read out.

The aria-describedby attribute should be used to provide supplemental content to an element's label – in addition to the label – rather than to label it directly. Examples of this might be to provide "helper text" about input format or other requirements when completing a form field, or to associate an error message with a specific input.

<label for="textbox-1">Date</label>  
<input type="text" id="textbox-1" aria-describedby="description-1">
<span id="description-1">Use mm/dd/yyyy format</span>

The use of aria-describedby in this example will let all users know the format of the date to enter in this text input. This will announce to a screen reader user when focus is placed on the form field.

<label for="username">Username</label>  
<input type="text" id="username" aria-describedby="username-error">
<span id="username-error">Username is required</span>

In this example, aria-describedby will programmatically associate the error message with the text input field, which allows screen reader users to hear the error message when the form field is focused. Sighted users will see the error message next to the text input field when it appears.

No ARIA is better than bad ARIA!

If in doubt, leave it out! Unfortunately, it's too common to find seemingly well-intentioned ARIA labels that actually make things worse for folks using assistive technologies. Meaningful and accurate labels can benefit everyone, including screen reader users, voice control users, users with cognitive issues, and all other users!

Screen reader users don't need "extra" instructions like "click here to activate the button" or "extra" information such as "this is a checkbox" so don't add this type of content into element labels. ARIA labels are only available to browsers and screen reading software, and can cause frustration and extra work for a voice control user when a visible label that doesn't match the accessible name. Generally speaking, don't add labels using ARIA if it provides a different user experience to a particular user group. Don't treat users with a disability differently than you would treat other users.

If something is important enough to add using ARIA, consider whether it should be added for all users. Overuse or misuse of the aria-label attribute can be indicative of larger problems within a code base or development processes. There is more than one way to write accessible code, but please be judicious in your use of ARIA for labeling purposes and just use native semantic HTML whenever possible.

Resources for further reading

One last thing

I want to express my sincere appreciation to Eric Bailey for his excellent editorial suggestions on this article, and to Manuel Matuzovic for putting this whole thing together (again!). Thank you both!

About Suzy Naschansky

Suzy started writing HTML code with version 3.2 but has focused on digital accessibility for the past several years to atone for the inaccessible websites she previously made or contributed to. Shifting left, she is now a Digital Accessibility Consultant/UX Architect in the Twin Cities, Minnesota, USA region. She firmly believes that accessibility is everyone's job and that it's easier to put the blueberries in the muffins before they're baked.

LinkedIn: snaschansky
Twitter: @cfdbchick
Website: naschansky.com