HTML Guides for aria-label
Learn how to identify and fix common HTML validation errors flagged by the W3C Validator — so your pages are standards-compliant and render correctly across every browser. Also check our Accessibility Guides.
The aria-label attribute defines an accessible name for an element, providing a text label that assistive technologies (like screen readers) can announce to users. It’s especially useful when there’s no visible text label on screen, such as for icon buttons or navigation landmarks. However, aria-label doesn’t work on every HTML element — it only has an effect on elements that have roles which support name from author.
According to the ARIA specification, aria-label is designed to work with interactive elements (like <button>, <a> with href, <input>), landmark and structural roles (like <nav>, <section>, <form>), images (<img>), and elements with explicit widget or landmark roles. When applied to generic elements that have no role (or only the generic implicit role), such as <div> or <span>, the attribute is effectively ignored by assistive technologies. This means users of screen readers won’t hear the label, defeating its purpose entirely.
This matters for several reasons:
- Accessibility: Developers may believe they’ve provided an accessible label when they haven’t. Users relying on screen readers will miss the information entirely.
- Standards compliance: The ARIA in HTML specification explicitly prohibits aria-label on elements where it has no effect, and the W3C validator flags this as a warning.
- Maintainability: Meaningless attributes add noise to the codebase and can mislead future developers about the element’s purpose.
To fix this warning, either move the aria-label to an appropriate element, add an explicit role attribute that supports naming, use aria-label on a different wrapping element that supports it, or replace the approach with visible text or a visually-hidden CSS class.
Examples
Incorrect: aria-label on a <div> with no role
A plain <div> has the implicit generic role, which does not support naming. The aria-label will be ignored.
<div aria-label="User profile section">
<img src="avatar.jpg" alt="User avatar">
<p>Jane Doe</p>
</div>
Correct: Use a landmark element or add an appropriate role
Wrapping the content in a <section> element gives it the region landmark role (when labeled), making aria-label valid and meaningful:
<section aria-label="User profile section">
<img src="avatar.jpg" alt="User avatar">
<p>Jane Doe</p>
</section>
Alternatively, add an explicit role to the <div>:
<div role="region" aria-label="User profile section">
<img src="avatar.jpg" alt="User avatar">
<p>Jane Doe</p>
</div>
Incorrect: aria-label on a <span>
<span aria-label="Warning">⚠️</span>
The <span> has the generic role and does not support aria-label.
Correct: Use an appropriate role or element
<span role="img" aria-label="Warning">⚠️</span>
Incorrect: aria-label on a <p> element
<p aria-label="Important note">Please read the terms carefully.</p>
The <p> element has the paragraph role, which does not support naming via aria-label.
Correct: Use visible text or restructure
If you need to provide additional context, consider restructuring:
<section aria-label="Important note">
<p>Please read the terms carefully.</p>
</section>
Or simply ensure the visible text is sufficiently descriptive, removing the unnecessary aria-label:
<p><strong>Important note:</strong> Please read the terms carefully.</p>
Common elements where aria-label works correctly
<!-- Interactive elements -->
<button aria-label="Close dialog">✕</button>
<a href="/home" aria-label="Go to homepage">🏠</a>
<input type="search" aria-label="Search the site">
<!-- Landmark elements -->
<nav aria-label="Main navigation">
<ul>
<li><a href="/">Home</a></li>
</ul>
</nav>
<form aria-label="Newsletter signup">
<input type="email" aria-label="Email address">
<button>Subscribe</button>
</form>
<!-- Images -->
<img src="chart.png" aria-label="Sales data for Q4 2024">
Quick reference: elements that do not support aria-label
Without an explicit role, aria-label will be flagged on these common elements: <div>, <span>, <p>, <b>, <i>, <em>, <strong>, <small>, <code>, <pre>, <blockquote>, <ul>, <ol>, <li>, <dl>, <dt>, <dd>, <table>, <thead>, <tbody>, and <tfoot>, among others. If you need aria-label on one of these, consider whether a more semantic element or an explicit ARIA role is the right solution first.
An aria-label attribute on an <a> element is only valid when the link has an accessible role that supports naming — which means the <a> must have an href attribute or an explicit role that accepts a label.
When an <a> element lacks an href attribute, it has the implicit role of generic. The generic role is in the list of roles that do not support naming, so applying aria-label to it is invalid. This is because a generic element has no semantic meaning, and screen readers wouldn’t know how to announce the label in a meaningful way.
The most common cause of this error is using <a> as a placeholder or JavaScript-only trigger without an href. An <a> with an href has the implicit role of link, which does support aria-label, so the error won’t appear.
You have a few ways to fix this:
- Add an href to make it a proper link (most common fix).
- Add an explicit role that supports naming, such as role="button", if the element acts as a button.
- Use a <button> instead if the element triggers an action rather than navigation.
- Remove aria-label if it’s not needed, and use visible text content instead.
HTML Examples
❌ Invalid: aria-label on an <a> without href
<a aria-label="Close menu" onclick="closeMenu()">✕</a>
The <a> has no href, so its implicit role is generic, which does not support naming.
✅ Fix option 1: Add an href
<a href="/close" aria-label="Close menu">✕</a>
✅ Fix option 2: Use a <button> instead
<button aria-label="Close menu" onclick="closeMenu()">✕</button>
✅ Fix option 3: Add an explicit role that supports naming
<a role="button" tabindex="0" aria-label="Close menu" onclick="closeMenu()">✕</a>
Using a <button> (option 2) is generally the best choice for interactive elements that perform actions rather than navigate to a URL.
A div element without an explicit role resolves to the generic role, which does not support naming — so adding aria-label to a plain div is invalid.
The aria-label attribute provides an accessible name for an element, but not every element is allowed to have one. The ARIA specification defines certain roles as “naming prohibited,” meaning assistive technologies will ignore any accessible name applied to them. The generic role is one of these, and since a div without an explicit role attribute defaults to generic, the aria-label is effectively meaningless.
To fix this, you have two main options: assign an appropriate ARIA role to the div so it becomes a nameable landmark or widget, or switch to a semantic HTML element that already carries a valid role. Common roles that support naming include region, group, navigation, alert, and many others.
If the div is truly just a generic wrapper with no semantic meaning, consider whether aria-label is even needed. Perhaps the label belongs on a child element instead, or the content is already self-describing.
HTML Examples
❌ Invalid: aria-label on a plain div
<div aria-label="User profile section">
<p>Welcome, Jane!</p>
</div>
✅ Fix: Add an appropriate role
<div role="region" aria-label="User profile section">
<p>Welcome, Jane!</p>
</div>
✅ Fix: Use a semantic element instead
<section aria-label="User profile section">
<p>Welcome, Jane!</p>
</section>
The aria-label attribute cannot be used on an <i> element with its default implicit role (generic), because generic elements are not allowed to have accessible names.
The <i> element has an implicit ARIA role of generic, which is one of the roles explicitly prohibited from carrying an aria-label. This restriction exists because screen readers and other assistive technologies ignore accessible names on generic containers — so adding aria-label to a plain <i> element would silently fail to convey any meaning to users who rely on assistive technology.
This issue commonly appears when icon fonts (like Font Awesome) use <i> elements as decorative icons. If the icon is purely decorative, you should hide it from assistive technology with aria-hidden="true" and place the accessible label on a parent or sibling element instead. If the icon conveys meaning on its own, you can assign an appropriate role like role="img" so the aria-label is actually announced.
HTML Examples
❌ Invalid: aria-label on a plain <i> element
<button>
<i class="icon-search" aria-label="Search"></i>
</button>
✅ Fix 1: Decorative icon — hide it, label the parent
<button aria-label="Search">
<i class="icon-search" aria-hidden="true"></i>
</button>
✅ Fix 2: Meaningful icon — assign role="img"
<button>
<i class="icon-search" role="img" aria-label="Search"></i>
</button>
The aria-label attribute cannot be used on a custom element like <menu-item> when it has no explicit role attribute, because it defaults to the generic role, which is in the list of roles that prohibit aria-label.
Custom elements without an explicit role are treated as having the generic role (equivalent to a <span> or <div> in terms of semantics). The WAI-ARIA specification prohibits aria-label on several roles, including generic, because naming these elements creates a confusing experience for assistive technology users — a generic container with a label doesn’t convey any meaningful purpose.
To fix this, you need to assign a meaningful role to the <menu-item> element that supports accessible naming. Common choices include role="menuitem", role="link", or role="button", depending on what the element actually does. Since this appears to represent a menu item that navigates to a page, role="menuitem" is likely the most appropriate.
HTML Examples
❌ Invalid: aria-label on an element with implicit generic role
<menu-item
submenu-href="/page"
label="some label"
submenu-title="some submenu title"
aria-label="some aria label">
</menu-item>
✅ Valid: adding an explicit role that supports aria-label
<menu-item
role="menuitem"
submenu-href="/page"
label="some label"
submenu-title="some submenu title"
aria-label="some aria label">
</menu-item>
If the aria-label isn’t actually needed (for example, if assistive technology already receives the label through other means in your component), another valid fix is to simply remove aria-label entirely.
A span element has an implicit ARIA role of generic, and the aria-label attribute is not allowed on elements with that role.
The span element is a generic inline container with no semantic meaning. Its default ARIA role is generic, which is one of several roles that prohibit naming via aria-label or aria-labelledby. This restriction exists because screen readers are not expected to announce names for generic containers — adding aria-label to them creates an inconsistent and confusing experience for assistive technology users.
To fix this, you have two main options:
- Assign an explicit role to the span that supports naming, such as role="img", role="group", role="status", or any other role that allows aria-label.
- Use a different element that already has a semantic role supporting aria-label, such as a button, a, section, or nav.
If the span is purely decorative or used for styling, consider using aria-hidden="true" instead and placing accessible text elsewhere.
HTML Examples
❌ Invalid: aria-label on a plain span
<span aria-label="Close">✕</span>
✅ Fixed: assign an appropriate role
<span role="img" aria-label="Close">✕</span>
✅ Fixed: use a semantic element instead
<button aria-label="Close">✕</button>
✅ Fixed: hide the decorative span and provide text another way
<button>
<span aria-hidden="true">✕</span>
<span class="visually-hidden">Close</span>
</button>
The aria-label attribute is not allowed on a label element that is associated with a form control through the for attribute.
A <label> element already provides an accessible name for the form control it’s associated with. Adding aria-label to the <label> itself creates a conflict: the aria-label would attempt to override the label’s own accessible name, but the label’s visible text is what gets passed to the associated form control. This redundancy is not only unnecessary but explicitly prohibited by the HTML specification.
The <label> element’s purpose is to be the accessible label for another element. If you want the form control to have an accessible name, simply put that text inside the <label> element as visible content. If you need to provide a different accessible name directly to the form control, place the aria-label on the input element instead.
Incorrect Example
<label for="input_email" id="label_input_email" aria-label="Email">
Email
</label>
<input type="email" id="input_email">
Correct Example
The simplest fix is to remove the aria-label from the <label>, since the label’s text content already serves as the accessible name for the input:
<label for="input_email" id="label_input_email">
Email
</label>
<input type="email" id="input_email">
If you need the accessible name to differ from the visible label text, place aria-label on the input instead:
<label for="input_email" id="label_input_email">
Email
</label>
<input type="email" id="input_email" aria-label="Your email address">
Validate at scale.
Ship accessible websites, faster.
Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.
Pro Trial
Full Pro access. Cancel anytime.
Start Pro Trial →Join teams across 40+ countries