About This Accessibility Rule
When an interactive element displays visible text, like a button that says "Submit", users expect that text to be the element's name. Developers sometimes use aria-label or aria-labelledby to set an accessible name that differs from the visible text. Sighted users then see one name while assistive technologies announce another.
This is a serious accessibility problem, and speech input users get the worst of it. They operate a page by speaking the names of the controls they see. If someone sees a link labeled "Next Page" and says "click Next Page", but the accessible name is "OK", the command fails. The user has no way to find out the programmatic name, so for them the control might as well not exist.
Screen reader users and people with cognitive disabilities are affected too. When a screen reader announces a name that doesn't match the visible label, users can't be sure they're on the right element. People who rely on a consistent, predictable interface have one more inconsistency to work around.
This rule checks Success Criterion 2.5.3: Label in Name (Level A), which is part of both WCAG 2.1 and WCAG 2.2. When a user interface component has a visible text label, its accessible name must contain that text. That way people can operate the component with the words they see, whatever input method they use.
Starting with axe-core 4.14, this rule runs by default. Earlier versions shipped it as an experimental rule that tools had to turn on, and Rocket Validator already did. What changed in 4.14 is how the rule compares the text, described below.
Which elements are checked
The rule applies to elements that meet all three conditions:
- It has a widget role that supports name from content:
button,checkbox,gridcell,link,menuitem,menuitemcheckbox,menuitemradio,option,radio,searchbox,switch,tab, ortreeitem. - It has visible text content.
- It has an
aria-labeloraria-labelledbyattribute that overrides the default accessible name.
How the visible text is compared
Axe compares the visible text with the accessible name word by word, ignoring case. Before comparing, it cleans up both strings:
- Anything inside parentheses is removed, including nested parentheses. A visible "Download report (PDF, 2 MB)" is compared as "download report".
- Emoji are removed, and other punctuation and symbols separate words, so "sign-in" becomes the two words "sign" and "in".
- Full-width and other compatibility characters are normalized to their plain forms.
- For scripts written without spaces between words, such as Chinese, Japanese, Korean or Thai, the browser's word segmenter splits the text into words.
- Icon font ligatures, such as the
arrow_forwardtext that Material Icons turns into an arrow, are not counted as visible text.
The rule passes when all the words of the visible text appear in the accessible name, in the same order, with no other words between them. The accessible name can have extra words before or after.
Axe matches whole words. Before 4.14, it only checked whether the visible text appeared somewhere inside the accessible name, so a button showing "Subscribe" with aria-label="Unsubscribe" passed. It fails now, because "subscribe" and "unsubscribe" are different words.
When axe asks for a manual review
Sometimes axe can't decide, so it reports the element as needing review instead of failing it. That happens in two situations.
The first is text a person can't read as a label. If the visible text or the accessible name is a single non-digit character (like "×" or "›"), contains only punctuation or symbols, or is a symbolic string such as "aA" or "abc", axe leaves the call to you.
The second is text that may be a value. On checkbox, radio, switch, menuitemcheckbox and menuitemradio elements, the visible text is sometimes the current state, like "On" or "Off", and not the label. If that text isn't in the accessible name, axe asks for a review.
How to Fix
- Make the accessible name include all of the visible text. If the element shows "Next Page", the
aria-labelmust contain the words "Next Page", in that order. Part of the text isn't enough, and neither is a different wording. - Start the accessible name with the visible text. It isn't strictly required, but speech input users may only say the beginning of a label, so it's the safer choice.
- Consider removing the
aria-labelentirely. If the visible text works as an accessible name on its own, you don't need an override, and letting the element take its name from its content is often the simplest fix. - When a toggle comes back for review, look at what its visible text is. A value like "On" doesn't need to be part of the name, so the review can be closed. If the text is the control's label, add it to the accessible name.
Examples
Failing: Accessible name doesn't match visible text
The visible text says "Next" but the accessible name is "OK":
<div role="link" aria-label="OK">Next</div>
Failing: Accessible name only contains part of the visible text
The visible text is "The full label" but the accessible name is "the full", which leaves out "label":
<button aria-label="the full">The full label</button>
Failing: The words are in a different order
Both strings contain the same words, but "Next Page" doesn't appear in that order in the accessible name:
<button aria-label="Page next">Next Page</button>
Failing: The visible word is only part of a longer word
"Subscribe" appears inside "Unsubscribe", but not as a whole word. This example passed before axe-core 4.14:
<button aria-label="Unsubscribe">Subscribe</button>
Passing: Accessible name matches visible text
Case differences and surrounding whitespace are ignored:
<div role="link" aria-label="Next Page">next page</div>
Passing: Accessible name contains the full visible text
The visible text "Next Page" appears, in order, within the accessible name:
<button aria-label="Next Page in the list">Next Page</button>
Passing: Punctuation and parenthesized text are ignored
The hyphen in "Sign-in" separates words, and the "(PDF, 2 MB)" note is removed before comparing:
<button aria-label="Sign in to your account">Sign-in</button>
<a href="/annual-report.pdf" aria-label="Download annual report">Download annual report (PDF, 2 MB)</a>
Passing: No aria-label override needed
When the visible text is already a good accessible name, leave out the aria-label:
<button>Next Page</button>
Passing: aria-labelledby references text that includes the visible content
<span id="btn-label">Search the full catalog</span>
<button aria-labelledby="btn-label">Search</button>
The visible text "Search" is part of the accessible name "Search the full catalog", so the rule passes. The accessible name also starts with the visible label, which is ideal for speech input users.
Needs review: The visible text is a single symbol
Axe can't judge whether "×" is meant as a label:
<button aria-label="Close dialog">×</button>
Needs review: The visible text is the switch's state
"On" isn't part of the accessible name "Dark mode", but it describes the switch's value, not its label:
<div role="switch" tabindex="0" aria-checked="true" aria-label="Dark mode">On</div>
Detect accessibility issues automatically
Rocket Validator scans thousands of pages with Axe Core and the W3C Validator, finding accessibility issues across your entire site.
Learn more:
Deque
Reference
Deque University - How To Fix
→
W3C
Reference
WCAG 2.1 - Success Criterion 2.5.3 Label in Name
→
W3C
Reference
WCAG 2.2 - Success Criterion 2.5.3 Label in Name
→
act-rules.github.io
ACT Rule - Visible label is part of accessible name
→
W3C
Reference
WCAG 2.1 - Failure of Success Criterion 4.1.2 due to a user interface control not having a programmatically determined name
→
W3C
Reference
WCAG 2.1 - Using label elements to associate text labels with form controls
→
W3C
Reference
WCAG 2.1 - Using aria-labelledby to provide a name for user interface controls
→
W3C
Reference
WCAG 2.1 - Using aria-label to provide an invisible label where a visible label cannot be used
→
W3C
Reference
WCAG 2.1 - Using the title attribute to identify form controls when the label element cannot be used
→
Help us improve our guides
Was this guide helpful?
🌍
Trusted by teams worldwide
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.
Scheduled Reports
API Access
Open Source Standards
€5
/ week
1K Weekly
1,000 monthly checks. Cancel anytime.
Get 1K Weekly →
Join teams across 40+ countries