惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 【当耐特】
WordPress大学
WordPress大学
T
The Exploit Database - CXSecurity.com
博客园_首页
MyScale Blog
MyScale Blog
The Cloudflare Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
美团技术团队
Stack Overflow Blog
Stack Overflow Blog
博客园 - 聂微东
M
MIT News - Artificial intelligence
Microsoft Security Blog
Microsoft Security Blog
F
Full Disclosure
V
V2EX
博客园 - Franky
博客园 - 三生石上(FineUI控件)
Hugging Face - Blog
Hugging Face - Blog
P
Proofpoint News Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
SecWiki News
SecWiki News
N
Netflix TechBlog - Medium
S
Secure Thoughts
酷 壳 – CoolShell
酷 壳 – CoolShell
Hacker News: Ask HN
Hacker News: Ask HN
爱范儿
爱范儿
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Webroot Blog
Webroot Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Martin Fowler
Martin Fowler
PCI Perspectives
PCI Perspectives
S
Security @ Cisco Blogs
Recorded Future
Recorded Future
Help Net Security
Help Net Security
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
AI
AI
Microsoft Azure Blog
Microsoft Azure Blog
K
Kaspersky official blog
G
GRAHAM CLULEY
H
Hackread – Cybersecurity News, Data Breaches, AI and More
C
CERT Recently Published Vulnerability Notes
U
Unit 42
T
Tor Project blog
Cloudbric
Cloudbric
Hacker News - Newest:
Hacker News - Newest: "LLM"
MongoDB | Blog
MongoDB | Blog
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
Security Latest
Security Latest
N
News and Events Feed by Topic
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

Ben Myers

Tag, You’re It: Blog Questions 2025 Don’t Use aria-label on Static Text Elements Subtitles, Closed Captions, and Open Captions: What’s the Difference? Lost in Translation: Tips for Multilingual Web Accessibility Build a Blogroll with Eleventy I’m a Spotless Giraffe. How I Write Alt Text for Code Snippets on Social Media The Curious Case of “iff” and Overriding Screenreader Pronunciations The Web Needs a Native .visually-hidden Create Shareable Automatic Captions for Live Online Events with Web Captioner A First Look at the Websites and Software Applications Accessibility Act Bill Style with Stateful, Semantic Selectors How I Doubled My Lighthouse Performance Score in One Night How to Fix Your Low-Contrast Text Build a Twitch Chatbot for Sharing Your Content Using Algolia Search Ben’s Humane Guide to Technical Blogging On the ‹dl› Takeaways From “Adapting Comics for Blind and Low Vision Readers: A Roundtable Discussion” Takeaways From Axe-Con 2021 I Finally Understand Eleventy’s Data Cascade. RSS Readers: Yet Another Case for Semantic Markup Implement a Skip Link for Navigation-Heavy Sites Out With The Old, In With The New Maintaining Focus Outlines for Windows High Contrast Mode Lexical and Dynamic Scope CSS Can Influence Screenreaders New Year, New Terminal: Alias Your Directories the Unix Way New Year, New Terminal: Alias Your Directories the Windows Way What Is ARIA? The Accessibility Tree How (Not) to Build a Button How Domino’s Could Topple the Accessible Web – Part 1: Public Accommodations
aria-label, aria-labelledby, and aria-describedby: What’s the Difference?
Ben Myers · 2020-12-07 · via Ben Myers

Introduction

ARIA is a set of HTML attributes designed to tweak how a webpage is exposed to assistive technology. It can be… a lot. There are presently 36 aria-* attributes, each with their own specific or general use cases, their own rules for compatible elements and roles, and their own browser/​screenreader support tables. On top of that, they can be hard to keep straight—when should you use aria-valuenow versus aria-valuetext, or aria-checked versus aria-selected?

I’ve written about ARIA before, but this time, I’d like to hone in on three ARIA attributes that, in my experience, are just similar enough to be confusing: aria-label, aria-labelledby, and aria-describedby.

Have you used these attributes before?

If you’ve used these attributes before, pause here and ask yourself: What’s the difference between aria-label, aria-labelledby, and aria-describedby? When might you use one over the other? Can they be used together?

Names and Descriptions

Behind the scenes, your browser packages up an alternative version of the DOM, called the accessibility tree, to expose to assistive technologies. This tree is made up of objects—bundles of properties that describe your elements’ functionality. Two of these properties are the accessible name and the accessible description.

The accessible name is a required field. It’s the key way that elements are exposed and announced by assistive technologies. One handy way to think about the name is that it’s probably how you’d describe the element to someone else using the page: “Select the Username field,” or “Click the Edit button.” Semantic HTML elements generally have their own default way of calculating their name. For instance, images use their alt text, buttons and links use their text contents, form fields use associated <label> elements, and so forth.

Names are critical for interacting with elements through assistive technology. Voice control users may say the name of a control, such as a button, aloud to interact with it. Additionally, some screenreader navigation modes, such as VoiceOver’s Rotor, allow users to skim through the page using only elements’ roles and names.

On the other hand, the accessible description is optional, and it represents supplemental information about the given element. Screenreaders and other assistive technologies may opt to skip over descriptions in some navigation modes such as continuous reading, where the description may cause needless clutter.

Let's revisit those initial questions.

Now that we’ve talked about names and descriptions, what do you think the difference between aria-label, aria-labelledby, and aria-describedby is? Has your answer changed?

ARIA gives web developers the tools to curate how elements on our page are exposed to assistive technology by modifying properties such as these! Let’s look at how we can use aria-label, aria-labelledby, and aria-describedby to curate useful names and descriptions.

aria-label

aria-label overrides an element’s name, replacing it with text that you specify. For instance, consider the following button:

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

By default, the button’s name would have been “×.” However, × is meant to be a multiplication symbol, and screenreaders will announce it as such. That means that, while this might be a visually appealing close button, it won’t be super useful or descriptive for disabled users who rely on assistive technology. To remedy this, we put aria-label="Close" on the button. The button’s name is now “Close,” which is much more descriptive and intuitive.

It can be tempting to use aria-label all over the place to tailor announcements and pronunciations for screenreader users, but, as with all ARIA, it’s important to be judicious. For one thing, while aria-label is well-supported for interactive elements, it’s not well-supported for static text elements. For another, such label overrides often rely on faulty assumptions about how users navigate your page. Finally, if you find yourself reaching for aria-label often, that may be a sign that you should reconsider your semantic markup or retooling your design to include more visual labels that everyone can access.

aria-labelledby

aria-labelledby also overrides an element’s name, replacing it with the contents of another element. aria-labelledby is set to the id of another element whose contents make up a useful name. You can think of it as kind of like a generalized version of the <label> element’s for attribute. This is useful when you already have another element that serves as a visual label for something. By linking the two elements with aria-labelledby like this, we ensure that we only have to update content in one place and our accessible name updates automatically. Something, something, Don’t Repeat Yourself.

One handy use case for aria-labelledby is labelling sections. When sections are labelled, screenreader users can skim through them like a table of contents, using them to skip to sections of the page they care about. Usually, these sections already have a heading element that can serve as a nice, convenient label!

<section aria-labelledby="intro-heading">
	<h2 id="intro-heading">
		Introduction
	</h2>
	<p></p>
</section>

aria-labelledby shares many of the same caveats as aria-label such as compatible elements and user expectations. Additionally, aria-labelledby will supercede aria-label if both attributes are provided.

aria-describedby

aria-describedby sets an element’s description to the contents of another element. Like aria-labelledby, aria-describedby takes an id. Descriptions are helpful for providing longer-form, supplemental information about an interface control that should probably be exposed along with the rest of the element, but which wouldn’t make sense as part of the element’s name.

We could, for instance, use aria-describedby to link an input with an element that provides further details about the input’s expected format:

<form>
	<label for="username">Username</label>
	<input id="username" type="text" aria-describedby="format" />
	<p id="format">
		Username may contain alphanumeric characters.
	</p>
</form>

The above input will have the name “Username” (given to it by its <label>) and the description “Username may contain alphanumeric characters.” That means that while assistive technologies will call the input field “Username,” when the user actually navigates to the field, they’ll be informed of both its name and the expected format. Nifty.

Because descriptions are supplemental, they may not be exposed to the user in every navigation mode. This is a great thing, because it reduces clutter! For instance, many screenreader users will skim through a whole form to find out which fields are available before filling it out, but they wouldn’t need your descriptions until they start filling out each field. However, this does mean you should go in with the assumption that your provided description might not be guaranteed.

Providing Multiple IDs

Should you need, both aria-labelledby and aria-describedby support passing multiple IDs. When assembling the element’s name or description from multiple elements, the browser will concatenate each element’s contents into one big string.

Expanding on our username field example from earlier…

<form>
	<label for="username">Username</label>
	<input id="username" type="text" aria-describedby="length format" />
	<p id="length">
		Username must be 6 to 15 characters.
	</p>
	<p id="format">
		Username may contain alphanumeric characters.
	</p>
</form>

Our input’s full description now reads “Username must be 6 to 15 characters. Username may contain alphanumeric characters.”

aria-labelledby and aria-describedby interact with a few other attributes—namely, hidden or aria-hidden—in an interesting way. In an ideal, 100% compatible world, when you set hidden or aria-hidden=“true” on an element, that element won’t be exposed to assistive technology so, for instance, screenreaders won’t announce it. But what happens if you use a hidden element’s id in another element’s aria-labelledby or aria-describedby?

What happens is kind of cool—the hidden element stays hidden, but its contents populate the other element’s name or description anyways! You might not use this with aria-labelledby because using aria-label is probably easier in these cases. Where this comes in handy, though, is with descriptions.

Currently, there isn’t an aria-description attribute yet, though this attribute is on its way. Until it arrives and is widely supported by browsers and assistive technology alike, however, the only way to set an element’s description is to introduce another DOM node to the page. By default, this means that you have a new node that assistive technology could expose independently of the labelled/described element. In other words, you could be introducing potentially confusing clutter. We could place an aria-hidden on our description to minimize that misleading clutter.

But enough talk—here’s an example!

<table>
	<thead>
		<tr>
			<th role="columnheader" scope="col" aria-sort="none">
				<button aria-describedby="sort-description">
					<svg><!-- some sort icon --></svg>
					Name
				</button>
			</th>
			<th></th>
		</tr>
	</thead>
	<tbody>

	</tbody>
</table>

<p id="sort-description" hidden>
	Sort this table alphabetically by name.
</p>

In this example, we have a table whose column headers have buttons that will sort the table. That sorting behavior is made evident for sighted users with some recognizable sort icon, but blind users wouldn’t get any cues to the buttons’ functionality. To compensate, we give the button a description using aria-describedby, pointing to a <p> tag outside of the table. We wouldn’t want users to navigate to the <p> on its own, however, so we apply hidden to it. Now our sort button has a description of “Sort this table alphabetically by name.” without any of the ensuing clutter! 🙌🏻

TL;DR

aria-label, aria-labelledby, and aria-describedby can all be used to bring extra clarity to a given element when it’s exposed to assistive technology.

  • aria-label overrides an element’s name with contents you specify.
  • aria-labelledby replaces an element’s name with contents from another node on the page. You’d use this when you’d already have a visible label anyways.
  • aria-describedby sets your element’s description to the contents of another node on the page. This is great for noncritical, supplemental information.
  • aria-description… is coming.

As always, be sure to test your ARIA in a variety of browsers and assistive technologies to be confident that your ARIA is adding clarity rather than taking it away.