Short answer: ARIA labels are attributes you add to HTML elements to provide an accessible name for assistive technologies like screen readers. Use `aria-label` when you want to override an element’s visible label, and `aria-labelledby` when you want to point to an existing visible element as the label. Always prefer native HTML semantics first.
Key takeaways
- ARIA labels provide accessible names for elements without visible text.
- Use aria-label to give a hidden label; use aria-labelledby to reference a visible label.
- Always prefer native HTML elements like over ARIA when possible.
- Don’t add ARIA labels to elements that already have a visible label.
- Test with a screen reader to verify your labels work as intended.
What you will find here
- What Is an ARIA Label?
- When Should You Use ARIA Labels?
- aria-label vs. aria-labelledby: What’s the Difference?
- When to Use aria-labelledby
- Common Mistakes with ARIA Labels
- ARIA Labels vs. Native HTML: Which to Choose?
- Step-by-Step: Adding an ARIA Label
- Testing and Verifying ARIA Labels
- How ARIA Labels Interact with CSS and Hidden Content
- Handling Dynamic Labels and JavaScript Frameworks
ARIA labels are one of the first accessibility tools many developers learn. They let you add an invisible label to an element so screen readers can describe it. But they’re also easy to misuse. This guide covers the two main ways to label elements with ARIA, when to use each, and where to avoid them.
What Is an ARIA Label?
ARIA stands for Accessible Rich Internet Applications. It’s a set of attributes you can add to HTML elements to improve accessibility when standard HTML isn’t enough. An ARIA label gives an element an accessible name — a text string that screen readers announce to describe the element.
There are two main attributes: aria-label and aria-labelledby. Both set the accessible name, but they work differently. aria-label contains the label text directly in its value. aria-labelledby references one or more other elements by their id, combining their visible text into the label.

When Should You Use ARIA Labels?
You should use ARIA labels only when an element doesn’t have a visible label that screen readers can pick up. For example, an icon button with no text: <button aria-label="Close">×</button>. The visible content is just a symbol, but the ARIA label tells screen readers what it does.
Another case is a search input that lacks an adjacent <label> element. You could add aria-label="Search" directly to the input. But a better approach is to use a real <label> element, if you can. Native HTML labels work for more users and devices.
A common mistake is putting aria-label on an element that already has a visible text label, like a link that says “Read more.” The visible text becomes the accessible name, so the ARIA label either duplicates it or overrides it — both confuse users.
aria-label vs. aria-labelledby: What’s the Difference?
aria-label sets the accessible name to whatever string you write as its value. It overrides any visible text inside the element. For example:
<button aria-label="Close modal">×</button>
Screen readers will say “Close modal” instead of reading the multiplication sign.
aria-labelledby, on the other hand, points to one or more other elements’ id values. The accessible name becomes the combined visible text of those elements. This is useful when you want to reuse visible text as the label, especially for complex components.
If both aria-labelledby and aria-label are present, aria-labelledby takes precedence. If that reference doesn’t exist, aria-label is used as a fallback.
When to Use aria-labelledby
Use aria-labelledby when you have visible text on the page that already describes the element. For example, a region with a heading:
<div role="region" aria-labelledby="section-heading">
<h2 id="section-heading">Contact Info</h2>
<p>...</p>
</div>
Here, the landmark region gets its accessible name from the visible heading. The screen reader announces “Contact Info region.” This keeps the experience consistent for all users.
Another use is form inputs that have a visible label but aren’t properly associated. You can tie them together with aria-labelledby:
<label id="name-label">Full name</label>
<input aria-labelledby="name-label">

Common Mistakes with ARIA Labels
The biggest mistake is overusing ARIA labels. Many elements don’t need them. If you have a native <button> with visible text, you don’t need aria-label. If you have a <label> properly linked to an input via for attribute, you don’t need ARIA either.
Another mistake is using aria-label on elements that don’t accept it. Not every HTML element can have an accessible name set this way. For example, <div> and <span> without an explicit role may not announce the label. Add a role if you need to label a generic container.
A third pitfall is dynamic content: updating aria-label with JavaScript but forgetting to test. Screen readers may not announce the change unless you also manage focus or use a live region. Always test with real assistive technology.
ARIA Labels vs. Native HTML: Which to Choose?
Here’s a quick comparison to help you decide:
| Approach | When to Use | Example |
|---|---|---|
Native <label> | Form inputs with visible label text | <label for="email">Email</label><input id="email"> |
aria-label | Elements with no visible text (icon buttons, close icons) | <button aria-label="Close">×</button> |
aria-labelledby | When visible text elsewhere describes the element | <div role="region" aria-labelledby="heading-id"> |
If in doubt, start with native HTML. ARIA is a supplement, not a replacement. For more advanced testing, check out How to Test Your Site for Accessibility Issues and Color Contrast Ratios: A Practical Developer Guide.
Step-by-Step: Adding an ARIA Label
- Identify the element that needs an accessible name but lacks a visible label. For example, a search button with a magnifying glass icon.
- Choose the right attribute: Use
aria-labelif you can write a short descriptive text. Usearia-labelledbyif the page already has visible text that describes it. - Write the label in plain language. Be concise but clear. “Search” is better than “Click here to search.”
- Add the attribute directly to the element. For
aria-label:<button aria-label="Search">🔍</button>. Foraria-labelledby:<input aria-labelledby="search-label">with a matching<span id="search-label">. - Test with a screen reader like NVDA or VoiceOver. Listen to how your element is announced. If it sounds wrong, revise the label.
Testing and Verifying ARIA Labels
Even with perfect syntax, your ARIA labels may not work as expected. The only reliable test is using a real screen reader. Keyboard testing also helps: tab to the element and confirm focus moves correctly. For a deeper walkthrough, read our Test Your Site for Accessibility Issues: A Developer’s Guide.
Developer tools in browsers can inspect the computed accessible name. In Chrome DevTools, the Accessibility pane shows the name for the selected element. If it’s blank or wrong, check that the ARIA attribute is on the right element and that there are no conflicting attributes.
How ARIA Labels Interact with CSS and Hidden Content
When you use aria-label on an element, the label text is not visible on screen. That can be a problem if users rely on visual cues. If the element has no visible text, consider adding a .sr-only class that renders the label text visually hidden but accessible. This gives sighted screen reader users the same context.
For aria-labelledby, make sure the referenced element is visible or at least accessible to assistive technology. If you hide the heading with display: none or visibility: hidden, the label won’t be computed. Instead, use a class like .visually-hidden that clips the text off-screen but keeps it in the accessibility tree.
Handling Dynamic Labels and JavaScript Frameworks
Single-page apps often update content without a page reload. If you change an aria-label attribute with JavaScript, the change may not be announced. To force an announcement, you might need to move focus to the updated element or use aria-live region around it. For example, a dynamic status message:
<div role="status" aria-live="polite">
<span id="status-text">Loading...</span>
</div>
Then update the text inside #status-text, and the screen reader will announce it. aria-live="polite" waits for the user to finish their current action before speaking.
When using React or Vue, remember that aria-label updates may not trigger re-announcement unless the element’s accessible name is recomputed. In practice, switching aria-label from one string to another often works, but adding or removing the attribute entirely can be missed.
Frequently asked questions
What is the difference between aria-label and aria-labelledby?
aria-label sets the accessible name directly from its attribute value. aria-labelledby references one or more element IDs whose visible text becomes the accessible name. aria-labelledby takes precedence if both are present.
Can I use aria-label on any HTML element?
Technically yes, but it only works for elements that have an accessible name property. For generic divs and spans, you may need to add a role like button or region for the label to be exposed to assistive technology.
Does aria-label override visible text?
Yes, aria-label overrides the element’s visible content as its accessible name. Screen readers will announce the aria-label value instead of the text inside the element.
Should I use aria-label for form inputs?
Generally no. Use a native element with the for attribute. But if you cannot use a visible label, aria-label on the input is acceptable as a fallback.
How do I test if my ARIA labels work?
Use a screen reader like NVDA (Windows) or VoiceOver (macOS). Also check the browser’s accessibility panel—Chrome DevTools’ Accessibility tab shows the computed accessible name for any element.
3 thoughts on “Beginner’s Guide to ARIA Labels in HTML”