When native HTML semantics alone cannot communicate the purpose of an element, Accessible Rich Internet Applications (ARIA) labeling techniques fill the gap. These techniques let developers attach human-readable names and descriptions to controls, landmarks, and custom widgets so that screen readers and other assistive technologies can announce them meaningfully. The three core attributes—aria-label, aria-labelledby, and aria-describedby—each solve slightly different problems, and understanding when to use each one is essential to building truly accessible interfaces.
ARIA labeling works within the broader accessible name computation defined by the W3C. Browsers follow a specific algorithm to determine what name to announce for a given element: they check for aria-labelledby first, then aria-label, then the element's native label (such as a <label> element or alt attribute), and finally the element's content. Knowing this order of precedence helps developers avoid conflicts where multiple sources compete and an unintended name wins.
Why ARIA labeling techniques matter
Accessible names are the primary way screen reader users identify interactive elements. A button without a discernible name is announced simply as "button," leaving a blind user unable to determine its function. A navigation landmark repeated multiple times on a page—such as primary navigation and footer navigation—becomes indistinguishable without a unique label.
Without proper labeling:
- Screen reader users hear generic or empty announcements, making it impossible to navigate efficiently.
- Voice-control users cannot target elements by name, because there is no name to speak.
- Automated accessibility audits (including WCAG 2.x conformance checks) flag elements that lack accessible names, generating validation errors.
- WCAG Success Criteria 1.3.1 (Info and Relationships), 4.1.2 (Name, Role, Value), and 2.4.6 (Headings and Labels) can all fail when labeling is missing or incorrect.
Getting ARIA labeling right benefits everyone: it improves usability for assistive technology users, satisfies automated validators, and often clarifies the interface for sighted users as well.
How ARIA labeling techniques work
aria-label
The aria-label attribute provides an accessible name as a plain string directly on an element. It overrides the element's inner text for assistive technologies while leaving the visual rendering unchanged. Use it when no visible text label exists or makes sense in the design.
aria-labelledby
The aria-labelledby attribute points to one or more id values of other elements whose text content should serve as the accessible name. Because it references visible text already on the page, it keeps the visual and accessible labels in sync. It takes the highest priority in the accessible name computation, so it will override aria-label and native labels.
aria-describedby
While not strictly a "labeling" attribute, aria-describedby works alongside labels by providing supplementary descriptions. Screen readers typically announce the accessible name first, then the description after a brief pause or on demand. It is ideal for conveying hint text, error messages, or additional context.
When to prefer native HTML
The first rule of ARIA is: don't use ARIA if a native HTML element or attribute will do the job. A <label> element associated with an <input>, or an alt attribute on an <img>, is more robust and requires less maintenance than an ARIA attribute. Reserve ARIA labeling for cases where native semantics fall short—custom widgets, duplicate landmarks, or icon-only buttons.
Code examples
Bad: icon button with no accessible name
<button class="btn-close">
<svg viewBox="0 0 24 24" width="24" height="24">
<path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2"/>
</svg>
</button>
A screen reader announces this as "button" with no indication of its purpose.
Good: icon button with aria-label
<button class="btn-close" aria-label="Close dialog">
<svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
<path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2"/>
</svg>
</button>
The aria-label provides the accessible name "Close dialog," and aria-hidden="true" on the SVG prevents redundant announcements.
Bad: duplicate navigation landmarks without labels
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
<!-- ...page content... -->
<nav>
<ul>
<li><a href="/privacy">Privacy</a></li>
<li><a href="/terms">Terms</a></li>
</ul>
</nav>
Screen readers list two "navigation" landmarks with no way to tell them apart.
Good: unique labels with aria-labelledby
<nav aria-labelledby="nav-primary-heading">
<h2 id="nav-primary-heading" class="visually-hidden">Primary navigation</h2>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
<!-- ...page content... -->
<nav aria-labelledby="nav-footer-heading">
<h2 id="nav-footer-heading" class="visually-hidden">Footer navigation</h2>
<ul>
<li><a href="/privacy">Privacy</a></li>
<li><a href="/terms">Terms</a></li>
</ul>
</nav>
Each <nav> now has a distinct accessible name derived from its associated heading.
Good: input with supplementary description via aria-describedby
<label for="new-password">New password</label>
<input
type="password"
id="new-password"
aria-describedby="password-hint"
/>
<p id="password-hint">
Must be at least 12 characters and include a number.
</p>
The <label> supplies the accessible name, while aria-describedby links the hint text so screen readers announce it as a description after the field name.
Bad: conflicting labels
<label for="email">Email address</label>
<input
type="email"
id="email"
aria-label="Enter your electronic mail"
aria-labelledby="some-nonexistent-id"
/>
Here aria-labelledby references an id that doesn't exist, resulting in an empty accessible name (since aria-labelledby wins the computation). Even if it did resolve, having three competing label sources creates confusion and maintenance headaches.
Good: single clear labeling source
<label for="email">Email address</label>
<input type="email" id="email" />
The native <label> is all that's needed. No ARIA required, no conflicts, and full screen reader support.
Related terms
Help us improve this glossary term
Scan your site
Rocket Validator scans thousands of pages in seconds, detecting accessibility and HTML issues across your entire site.