Everything you need to know about aria-label

Posted in:

One of the most common well-meaning but misunderstood accessibility recommendations is to use aria-label to make things more accessible.

It seems to make sense at first. It’s the ARIA that people are most likely to encounter and one of the easier ones to understand. And using an attribute seems more techy and less of a workaround than adding a hidden span.

The problem is that technical documentation often provides definitions and basic examples, but rarely includes real-world scenarios. Especially when it doesn’t quite match the situation you’re trying to use it for. It’s hard to know when not to use something or when a better alternative exists, because documentation usually focuses on what to fix, not how to choose the best approach.

With aria-label, like most ARIA attributes, it’s not that you’re going above and beyond by using one, like when you revisit your alt text to make sure it’s properly describing the image within its context. For all but a couple cases, you’re either using aria-label correctly or not.

It’s something that can and should be used in certain circumstances, but as things have evolved, we’ve come up with a better and more reliable option for a lot of use cases.

The options

When considering using aria-label, there are going to be a few additional options you’ll need to be aware of:

  • aria-label is used for a short title or name when that text isn’t already near it, and it should be concise.
  • aria-labelledby is used instead of aria-label when the text is already on the page.
  • aria-describedby is extra information about what the element is, what it does, or how to use it.
  • Screen reader-only text, or visually hidden text, is content added to the page that is then hidden from visual users with CSS.

About screen reader-only text

When you need to add some additional text to something to provide some additional context that a screen reader user might need, we can use a class to add some CSS to an element to hide it for visual users.

You add the class to whatever you want to hide, whether that’s to a container, like when you’re including instructions for screen reader users, or by adding a span to the part of the text you want to hide, like when you’re adding more text to a “Read More” link in a blog post grid.

Add this CSS to your theme and then add sr-only to what you want to hide.

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip: rect(0 0 0 0);
  overflow: hidden;
  white-space: nowrap;
}

If you’re using the block editor, there’s a WordPress plugin called Screen Reader Text Format you can use to make this process much easier.

An example

A common method for improving the heading structure of certain landmarks would be to use a screen reader-only heading.

<aside>
  <h2 class="sr-only">Sidebar</h2>
  <h3>Recent Posts</h3>
  …
  <h3>Follow Us</h3>
  …
</aside>

<footer>
  <h2 class="sr-only">Footer</h2>
  <h3>Get In Touch</h3>
  …
</footer>

This lets users navigate throughout the page a little easier while allowing things like footers and sidebars to use more semantic and visually appropriate heading levels.

When you should use aria-label

Labeling landmarks

When there are multiple instances of a navigation, aside, or other supported landmarks, a label will help screen reader users differentiate between them and navigate to them faster. If there’s a heading, use that to label the section with aria-labelledby and use aria-label when there isn’t.

You can use aria-labelledby on screen reader text, so if you’re using the hidden heading method for a sidebar, you can use that.

<header>
  <nav aria-label="Main">
    …
  </nav>
</header>

<footer>
  <div>
    <h2 id="footer-company-heading">Company Links</h2>
    <nav aria-labelledby="footer-company-heading">
      …
    </nav>
  </div>

  <div>
    <h2 id="footer-resources-heading">Resources</h2>
    <nav aria-labelledby="footer-resources-heading">
      …
    </nav>
  </div>
</footer>

You would only need to do this if there are multiple instances of these landmarks and leave out redundant descriptors like “navigation”.

An icon-only button

Ideally, the button will have the text, like “Close” instead of an x. But if that’s not possible, without proper context, a button with an image in it doesn’t have the context that visual users have.

<button aria-label="Close">
  <svg aria-hidden="true" focusable="false">
    <!-- icon content -->
  </svg>
</button>

Icon fonts, SVGs, or canvas

First, decide if it’s decorative. If it is, hide it from screen readers. If it’s not, for instance if it’s a data visualization, that’s when it will need some kind of label.

An decorative icon or icon font:

<p class="success-message">
  <svg aria-hidden="true" focusable="false">…</svg>
  Your changes have been saved.
</p>

An icon conveying meaning:

<svg role="img" aria-label="Warning: unsaved changes">
  <!-- warning triangle icon -->
</svg>

You would use that same markup for a chart with a simple description:

<svg role="img" aria-label="Bar chart showing revenue growth from 2020 to 2024">
  <!-- chart graphics -->
</svg>

A chart with a more complex description:

<div 
  role="img" 
  aria-labelledby="chart-title" 
  aria-describedby="chart-desc"
>
  <!-- Chart rendering here -->
</div>

<h2 id="chart-title">Monthly Sales Chart</h2>
<p id="chart-desc" class="sr-only">
  This chart shows monthly sales from January to December, with a peak in July and a drop in October...
</p>

And if that information below the chart is explained within the chart itself, you can add the screen reader-only class to the elements to visually hide them.

Custom widgets

Certain programming languages, elements, or other situations might arise where screen reader text might not work because it either breaks styling, is stripped out by a framework, or causes keyboard or focus issues. Custom select widgets, svg-only buttons, or other limitations would then need to use aria-label.

When you should use something else

There are a lot of situations where people will recommend using aria-label to make something more accessible, and while in a lot of those situations it can technically be right, there’s often a much better way to go about it.

There are some drawbacks to aria-label:

  • Not reliably translated.
  • Requires an additional place to go to update information.
  • Only allows plain text and can’t be styled.
  • Harder to view during testing.

Most of the time, screen reader text or using the proper HTML element is going to be the better option.

In rare cases, screen reader text has the potential to impact the layout and spacing, so if you do notice a layout shift of some kind, first check your CSS. If the class has been properly added and all the CSS definitions are being applied without being overwritten, you may have to use aria-label and notify your platform or developer of the issue.

So while aria-label isn’t technically wrong in these scenarios, it’s better to think of it as a last resort.

No form field labels

In almost every case, it’s going to make more sense to use a label. It’s better for all users.

But there are forms that might make sense without a label. The most common form that’s going to end up using a label that isn’t visible is a search form. (Though search forms aren’t the only type that would need aria-label.)

If you can add the screen reader-only class to the label, or even use aria-labelledby with the screen reader-only class on the heading or text, that’s going to be ideal.

Using the preferred screen reader-only class:

<form action="/search" role="search">
  <label for="search-input" class="sr-only">Search this site</label>
  <input type="search" id="search-input" name="q" placeholder="Search…" />
  <button type="submit" aria-label="Submit search">
    <svg aria-hidden="true" focusable="false">…</svg>
  </button>
</form>

Using aria-label:

<form action="/search" role="search">
  <input type="search" name="q" placeholder="Search…" aria-label="Search this site" />
  <button type="submit" aria-label="Submit search">
    <svg aria-hidden="true" focusable="false">…</svg>
  </button>
</form>

Links

Most of the time, you don’t need to completely replace link text. Better link text is helpful for everyone. And most of the time, you don’t need to add extra text to a link that only screen readers can access. Something like “Privacy Policy” doesn’t need any additional information or context. It’s a link that goes to the privacy policy. Extra text ends up making things unnecessarily wordy.

Consider changing the text of your link or button. A more descriptive link would probably help all users.

If you can’t change the text because of the design, layout, or some other reason, that’s when you’ll want to use screen reader-only text.

<a href="/blog">View all<span class="sr-only"> latest posts</span></a>

The only time you would use the aria-label instead is for some reason that’s outside of your control.

Images or linked images

The only time to use aria-label on an image is when it’s an SVG or there’s a limitation in the platform or site builder you’re using. You’ll want to report the issue to the developers and use aria-label in the meantime, but in almost every case, alt text is going to be the better choice.

Linked images are a little trickier to write alt text for, since they need to include the link destination and might not need to describe the image itself. If the image is linked to something like a popup or lightbox, it needs to be a button, which means you’ll want to include the image with alt text and a hidden button that has unique text, so this is a little more complicated to implement. Both of these situations should use methods other than aria-label wherever possible.

Background images

A background image is considered decorative. So if an image being used in the background needs alt text, it’s better to insert an image and use CSS to style the image. The CSS property object-fit is what will let you treat an image like a background image. This also means that if CSS doesn’t load, the image will still be shown.

Take a look at the WordPress cover block to see how they position an image inside of a container to look like a background image but function as an image.

If you’re limited by the platform or builder for some reason, reach out to them and ask them to add the option for the more modern and flexible implementation of image insertion. Once you’ve reached out to them, in the meantime you can set role="image" on the container and use aria-label for what you would add as the alt text.

Inline images with text

When you have an image or SVG taking the place of a word or conveying a meaning meant to be read together with the text, you’re going to want to test it. Proper alt text will usually be enough, but images used in this way can sometimes be unpredictable, especially when the layout is being manipulated with CSS.

As with most things, if you can use a non-aria-label method and it works, that’s the way to go. But if it’s confusing and not something you can change, it might make more sense to add an aria-label to the wrapping element.

When you shouldn’t use aria-label

Any situation not mentioned in the previous two sections would not be an appropriate situation to use aria-label. It means you’re using the attribute for something it wasn’t intended for and will behave in unexpected ways.

Use alt text, use labels, use screen reader-only text, use other attributes.

If you have a scenario where you think aria-label should be used that hasn’t been mentioned, it’s possible I haven’t encountered it yet. The internet is always evolving. Reach out and we can discuss it, and I can let you know if you’re onto something!

How to decide

You have the few situations when you’ll need to make sure you add aria-label to an element (multiple landmarks, icon-only buttons, image-like elements).

Most of the time, when you’re adding other things to your page that you think might need some extra content for screen reader users, you can ask yourself a few questions. There are some additional questions you can ask depending on the specific element, but generally you’re going to ask yourself:

  • Does this actually need more context or is it ok to leave as it is?
  • Can I add something visible or rephrase this for all users instead?
  • Is there something else nearby that can be used as the label? (Use aria-labelledby.)
  • Can I add some extra hidden text to this? (Use screen reader-only text.)

If you’ve answered no to each question, it might be an aria-label situation.

As always, take extra care when using ARIA and test as best you can! This will make sure that everyone is able to interact with your site and get what they came for.

Discover a hands-on approach to learning how to make your website more accessible.

Through one manageable task per week, you’ll not only learn about what makes a more accessible site, but be actively making your site more accessible in the process.