The other day I was skimming Webkit’s Safari Technology Preview 153 release notes and noticed that they had added support for aria-description.

I always found it odd that developers could set an element’s accessible name/label with the aria-label and aria-labelledby attributes, but only had aria-describedby for setting accessible descriptions. So seeing aria-description being added to Safari was an interesting surprise.

I decided to do a mini dive and test of support for aria-description to fill in my knowledge gap and be prepared to use it when the time comes. A sort of crash-course, if you will. I’m sharing my findings here in case it’s valuable for anyone else.

Current status #

The aria-description property is part of the Accessible Rich Internet Applications 1.3 draft specification. This ARIA GitHub issue provides a bit more context on how it was added. Even though ARIA 1.3 is still in the draft stage, some browsers began adding aria-description support back in 2021.

Glancing at the support table on a11ysupport.io, Chrome, Edge, and Firefox currently appear to have good support for it.

Support table for aria-description from a11ysupport.io. The table shows JAWS, Narrator, NVDA, Orca, and TalkBack supporting it with Chrome, Edge, and Firefox. It then shows VoiceOver on Mac and iOS with Safari not supporting it.

So once this feature moves from Safari’s beta to the public release, it will have support in the four major browsers.

Accessible descriptions #

Why they’re important #

When sighted users see a control on a web page, they can scan its text and anything near it to understand it. In contrast, non-sighted and visually-impaired users rely on screen readers that step through a page’s elements one-by-one and announce them. These screen readers lean on the accessible name and description to give users valuable information about an element.

For interactive items, accessible names convey to these users what exactly it is. Without a name the control is effectively useless to them, so it should be concise and to-the-point – ex: a button labeled "login", "submit", or "help".

But sometimes there’s supplementary content, instructions, or details that, while not as important as the item’s name, are still helpful for the user to use or understand a control. This complementary information, which can be longer and more verbose, is the accessible description – ex: "the tracking # is the 12-digit number that begins with 'Z'" or "passwords must be at least 8 characters".

Sure, screen reader users might manually find this information like they would anything else. But it’s also possible they miss it by jumping directly to an interactive element. So when we can programmatically associate this helpful info as an accessible description of an item we provide coverage for those situations.

A text input on the left and a button on the right. The text input as a label "Password" above as well as a line of text that says "Must be 8 characters long". The button is labelled "Settings" and has text below it which says "Opens a modal".

In the image above, if the secondary content is set as an accessible description of the interactive elements then screen readers would announce something like “Password, edit box, must be at least 8 characters long” and “Settings, button, opens a modal” when encountering those elements.

Without the accessible description present the announcements would simply be “Password, edit box” and “Settings, button”, leaving out helpful details.

Usage #

All interactive elements should have an accessible name, which in most cases is the item’s text value. If desired, developers can override that with the aria-label or aria-labelledby properties.

aria-label directly sets a text string as the element's new name, while aria-labelledby points to the id of a separate element(s) whose text will become the element's name.

html
<button aria-label="Edit Settings">Settings</button> <button aria-labelledby="buttonName">Settings</button> <p hidden id="buttonName">Edit Settings</p>

On the accessible description side, developers most-commonly use the aria-describedby attribute to give an element an accessible description. aria-describedby works similar to aria-labelledby, in that it accepts an id of an element located elsewhere on the page whose text describes the element.

html
<button aria-describedby="buttonDesc">Settings</button> <p id="buttonDesc">(Opens a modal)</p>

Here, the description is visually next to the button, so sighted users will see it before clicking. That we can create that same association for screen reader users means we’re creating an equal experience.

Developers also commonly hide elements visually while still linking them programmatically like this to provide certain information only to screen readers. An extension of the previous technique, it requires keeping that additional page element and applying the hidden attribute, hiding it with CSS, or adding a “visually hidden” class:

html
<button aria-describedby="buttonDesc">Settings</button> <p hidden id="buttonDesc">Opens a modal</p> <!-- or --> <p style="display: none;" id="buttonDesc">Opens a modal</p> <!-- or --> <p class="visuallyHidden" id="buttonDesc">Opens a modal</p>

Whether this is a good practice or not is outside the scope of this blog post, but nevertheless it is common.

But using the new aria-description now gives authors an option similar to aria-label which allows them to directly set accessible descriptions without the need for a second element, an option that was missing before.

html
<button aria-description="Opens a modal">Settings</button>

This is a much cleaner and maintainable approach than using the aria-describedby property with a hidden node.

If you’re at all curious how browsers determine an item’s name or description, you can check out the Accessible Name and Description Computation specification. Note that this does not reference aria-description yet as it is not formally standardized.

Translation concerns #

One drawback of using attributes like aria-description (and aria-label) that contain text content is that they aren’t consistently converted by translation tools. So screen reader users who browse the web in another language may encounter a barrier when hearing an announcement that they don’t understand.

Adrian Roselli’s article aria-label Does Not Translate dives into this issue with the aria-label property, which has been around longer with better support. He finds that translation for that is spotty at best. So this is likely to be as much, if not more, of an issue with aria-description.

I did my own quick test using Google Translate on a page featuring an element with both an aria-description and aria-label:

html
<button aria-label="Settings" aria-description="Opens a modal">Settings</button>

Translating the page from English to Portuguese resulted in the following markup:

html
<button aria-label="Definições" aria-description="Opens a modal">Definições</button>

In this case, the aria-label property did get translated while the aria-description did not, which is a problem. We can assume that other translation tools will have at least this same issue.

As a solution, Adrian recommends in his article to use an element’s default text or the aria-labelledby attribute for accessible naming. So for accessible descriptions we’d want to use aria-describedby to point to other page elements that do get translated.

Testing #

Scope #

Browsers and screen readers #

I tested the four major desktop browsers (Chrome, Edge, Firefox, Safari) with a screen reader that it is commonly paired with. Note that I’m testing with Safari Technology Preview 153, the beta release that just added aria-description support.

Update 11/18/2022: After a Mac software update to MacOS Ventura I retested using regular Safari.

  • JAWS (2021.2111.13) + Chrome (105) on Windows 10
  • NVDA (2022.2.2) + Firefox (103) on Windows 10
  • Narrator (2020) + Edge (105) on Windows 10
  • Old: VoiceOver + Safari Technology Preview 153 (16.0) on MacOS 12.5.1
  • New: VoiceOver + Safari (16.1) on MacOS 13.0.1

On desktop, I navigated to the test elements in two ways: 1) with the screen reader’s virtual cursor (arrow keys); and 2) with the tab key.

For mobile testing, I used two environments. Note that I'm using Safari in the iOS 16 beta.

  • TalkBack (13.1.02) + Chrome (105) on Android 11, Samsung Galaxy A20s
  • VoiceOver + Safari on iOS 16 beta, iPhone 13

On the mobile devices, I navigated the page using horizontal swipes to move the virtual cursor.

For more background on why I chose these combinations, see the “Testing scope” section of my article Screen readers and drag-and-drop, part 1.

Markup #

I tested a button element with the text “Settings”. For easy comparisons, I tested both the aria-description and aria-describedby properties.

html
<!-- version A --> <button aria-description="Opens a modal">Settings</button> <!-- version B --> <button aria-describedby="buttonDesc">Settings</button> <p id="buttonDesc">Opens a modal</p>

Results #

Let’s take a look at the support for accessible descriptions.

Screen reader results: aria-description and aria-describedby attributes
Browser / screen reader button with aria-description, via virtual cursor button with aria-description, via tab button with aria-describedby, via virtual cursor button with aria-describedby, via tab
JAWS + Chrome “Settings button” "Settings button opens a modal" "Settings button" "Settings button opens a modal"
NVDA + Firefox "Button opens a modal settings" "Settings button opens a modal" "Button settings" "Settings button opens a modal"
Narrator + Edge "Button opens a modal settings" "Settings button opens a modal" "Button opens a modal settings" "Settings button opens a modal"
VoiceOver + Safari “Settings button [pause] more content available” “Settings button [pause] more content available” “Settings button [pause] opens a modal” “Settings button [pause] opens a modal”
TalkBack + Android Chrome "Settings button opens a modal" N/A "Settings button opens a modal" N/A
VoiceOver + iOS Safari "Settings button" N/A "Settings button opens a modal" N/A

The desktop browsers had mixed support for aria-description.

JAWS + Chrome supported it only when navigating with the tab key. The pairing didn’t announce any accessible description with the virtual cursor.

NVDA + Firefox did announce aria-description with both the virtual cursor and tab key, which it oddly did not do for aria-describedby.

Narrator + Edge supported both properties in both navigation methods.

The big quirk though is with Mac’s VoiceOver + Safari. While it did recognize that an accessible description was present with aria-description, it did not announce the content as it did for aria-describedby. It instead announced “more content available” followed by instructions to use the shortcut “VO + CMD + / (slash)” to access it.

Screenshot of Mac VoiceOver's onscreen command box: "more content available, You are currently on a button. To click this button, press Control-Option-Space. Press Control-Option-Command-Slash to bring up more"

When the shortcut is used, a VoiceOver menu opens listing “More Content”, where you then need to arrow down to the description to hear it. That’s a pretty laborious process.

VoiceOver modal window: "More Content" heading with a one-item list below it containing the text "Opens a modal, description"

Note:

I mentioned earlier that unlike an accessible name, an accessible description can be more verbose. I wonder if this is VoiceOver’s way to mitigate the possibility of longform descriptive content.

On mobile, TalkBack + Android Chrome had support for aria-description where VoiceOver + iOS Safari did not.

Though I tested on iOS Safari 16’s beta as I did with desktop, the aria-description property was not supported. It’s possible that version of WebKit hadn’t yet been incorporated into iOS’s beta yet, so I’ll continue to monitor it and update as needed.

Conclusion #

aria-description is a nice addition to the ARIA suite of properties that will come in handy for those times where you absolutely must provide information only to screen reader users. It’s less markup and much simpler than the current method of referencing hidden elements with aria-describedby.

However, it’s not ready for production yet. There doesn’t appear to be any translation support currently in the largest online translation tool, a problem in our diverse world.

It also doesn’t have full support across the most popular browser and screen reader pairings – and this was with the nearly latest releases. If you go back even a handful of versions I imagine the support gets weaker and weaker. Many users do not upgrade their devices and software on a regular basis, so we can’t shut them out.

I’m glad I dove into this attribute and look forward to adding it to my toolbox in the future when it’s more widely supported.

Update – 09/12/2022 #

The same day I published this article, Apple released Safari 16 to the public. I just downloaded the public release for both MacOS and iOS and both do not have support for aria-description. So I'd assume that since there was support in the Safari desktop beta that it will be added in a Safari update in the next month or two.

Update – 11/18/2022 #

I updated my MacBook to MacOS Ventura (11.0.1), which pushed my Safari version to 16.1. I then tested Safari + VoiceOver for aria-description again and found that it is now supported and announced, albeit with the "more content available" quirk I listed above. I have edited the testing table above to reflect this.

Even though my iPhone has installed a couple of updates, bringing it to iOS 16.1.1, it still lacks support for aria-description. I'll update this article again when that changes.