Your button says “Send”. What does it answer to?
Somebody using Voice Control looks at your page, reads the button, and says “click Send”. If that button carries aria-label="Submit" the command matches nothing — no error, no feedback, and the only name that would have worked lives in an attribute that renders as nothing at all. That is SC 2.5.3 Label in Name, Level A, and every accessibility scanner you have ever run reports that button as a clean pass, because it does have a name. Paste a page and we will put what each control says next to what it answers to.
Free, instant, no signup and no card. We read the HTML your server sends, and nothing is stored.
Try the page with the most buttons on it — a checkout, a settings screen or a sign-up form. Free, instant, no signup and no card, and nothing is stored.
The Level A failure your scanner is structurally unable to report
Every automated name check asks the same question: does this control have an accessible name? That is SC 4.1.2 Name, Role, Value, and it is the right question — a button announced as “button” is useless. But a button reading “Send” with aria-label="Submit" answers that question yes. It has a name. It is announced. It passes, in axe, in Lighthouse, in WAVE, and in our own button checker.
SC 2.5.3 asks the second question, and nothing else does: is the name the same as the words on it? Both criteria are Level A, and the usual way a page fails the second is by someone adding an ARIA attribute to satisfy the first. That is what makes this one strange — it is close to impossible to fail without deliberately writing an accessibility attribute, and close to impossible to pass once one has been written carelessly.
What happens to somebody who speaks to your page
ON SCREEN <button aria-label="Submit">Send</button>
the user reads: Send
SPOKEN "click Send"
MATCHED AGAINST the accessible name: "Submit"
RESULT nothing. No error, no highlight, no feedback.
The name that would work is not on the screen,
is not in the tooltip, and is not discoverable
by any means available to the person trying.Voice Control on iOS and macOS, Dragon on Windows and Windows Speech Recognition all work this way: the user reads the interface aloud and the software matches the phrase against accessible names. A mismatch is not a degraded experience, it is a control that does not exist. And it reaches further than speech — anybody using a screen reader with the screen, which is most low-vision magnifier users, hears one word and reads another and has to work out which is real.
Twelve real sites, read live on 27 September 2026
Run against real home and sign-in pages before this page existed. What the spread shows is that this is not a careless-team defect — the sites that fail it are the ones with the most ARIA on them.
stripe.com 222 controls 13 Level A failures + 1 field
tailwindcss.com 96 controls 1 — "v4.3" answers to
"Select version of library"
shopify.com 195 controls 1 failure, 1 review
gov.uk 125 controls 1 failure, 1 review
vercel.com 183 controls 0 failures, 2 reviews
developer.mozilla.org 184 controls 0 failures, 1 review:
"Theme" → "Switch color theme"
bbc.co.uk 225 controls clean
theguardian.com 394 controls clean
wikipedia.org 401 controls clean (397 named by their own words)
news.ycombinator.com 230 controls clean
wordpress.org 88 controls clean
github.com/login 21 controls cleanStripe’s thirteen are one component, repeated: a customer card whose visible button reads “Read the story” and whose name is “Read Hertz’s story”. It is the disambiguation pattern everyone is taught — make repeated “Read more” links distinguishable in a screen reader’s link list — implemented in the one way that breaks speech input, by replacing the visible words instead of extending them. aria-label="Read the story: Hertz" would have done the same job and conformed.
What we refuse to call a failure
The expensive mistake a checker can make is telling a stranger their correct page is broken. Every rule below was added because an earlier draft of this tool got it wrong on a real site, and the numbers are what those drafts reported:
- A name longer than the label. 2.5.3 asks that the name CONTAIN the visible text, not equal it. “Send message to support” over “Send” is correct and is reported as clear.
- A decorative arrow. A link reading “Domains ↗” named “Domains” is right. Before the arrows block was stripped from the comparison this tool reported 13 Level A failures on wordpress.org and 9 on vercel.com, and every one of them was that arrow.
- A leading duration or count badge. A video card painted “1:31 Starship test flights” and named “Starship test flights. 00:01:31” is fine. That single pattern produced 21 false failures on bbc.co.uk.
- A card-sized link. Where a control wraps a heading, body copy and a call to action, the label is the heading. Demanding the name contain every word in the card invented failures on stripe.com.
- An icon-only control. No visible text means no label to compare. It has a real problem and it is SC 4.1.2, not this one.
- A control with no name at all. Where every child is aria-hidden, or aria-labelledby points at an element JavaScript fills later, there is no name to compare against. Counted, set aside, and said so.
Everything this checker reports
Five things it counts as a Level A failure, four it reports without counting against you, and an honest branch for a page whose controls do not exist until JavaScript runs.
The name shares no words with what is printed on the control
Cannot be spokenSC 2.5.3 Label in Name (Level A)
The control says one thing on screen and answers to another. Somebody using speech input reads the button, says the words they can see, and the command matches nothing — no error, no feedback, and no way to find out what the real name is, because it lives in an attribute nothing renders. This is the exact failure SC 2.5.3 was added to WCAG 2.1 to cover, it is Level A, and every name-presence checker in existence reports this control as a clean pass, because it does have a name. It is just not the one on it.
The fix: Delete the override and let the control be named by its own words — that is the correct answer far more often than people expect. Where the name genuinely needs to be longer than the label, the visible words must be at the START of it: aria-label="Send message to support" on a button reading "Send" is conformant; aria-label="Submit" is not.
Specific words on screen replaced by a generic name
Cannot be spokenSC 2.5.3 Label in Name (Level A)
The control carries real, specific words and an override throws them away for "link", "button", "submit", "click here" or "read more". This is almost always somebody trying to be helpful to a screen reader and making the page worse for two audiences at once: the speech-input user cannot say the visible words, and the screen-reader user gets a link list in which every entry is the word "link". The original text was better than its replacement in every respect.
The fix: Remove the aria-label entirely. A control with no override is named by its own contents, which is the specific text you already wrote.
Form field whose visible <label> is overridden by a different name
Cannot be spokenSC 2.5.3 Label in Name (Level A)
There is a real <label> element pointing at this field, with words in it that a person can see — and an aria-label on the field that wins outright and says something else. The label is still painted on screen, so a sighted speech-input user says it and nothing focuses. This pattern usually arrives when somebody adds aria-label to "help" a field that already had a perfectly good label, so the page goes from conformant to failing by the addition of an accessibility attribute.
The fix: Delete the aria-label. A field with an associated <label> is already named by it, correctly, on every assistive technology. If the name needs more than the label says, extend the label text instead — or put the extra words in aria-describedby, which adds description without replacing the name.
Submit button whose printed value is overridden
Cannot be spokenSC 2.5.3 Label in Name (Level A)
On <input type="submit"> and <input type="button"> the value attribute is not metadata — it is the text the browser paints on the button. An aria-label on the same element replaces the accessible name and leaves the painted word untouched, so the button reads "Send" and answers to something else. It is the same defect as a mislabelled <button>, made easier to miss because nothing about a value attribute looks like visible text.
The fix: Change the value if the wording is wrong; remove the aria-label either way. The two are not alternatives to each other — one is what people read and the other is what they can say.
aria-labelledby on a control, pointing at an id that is not on the page
Cannot be spokenSC 2.5.3 Label in Name (Level A) · SC 4.1.2 Name, Role, Value (Level A)
The control names its label by id and no element with that id ships in the HTML. The reference resolves to nothing. On a control with visible text the browser falls back to the text — which happens to be right, by accident, and will stop being right the moment somebody adds an id that matches. On a form field with no text there is no fallback and the field is announced as nothing at all. Either way the markup looks completely correct in review, which is why this one survives.
The fix: Check the id actually ships with the page rather than being rendered later, and that it is unique — a component pasted onto the page five times emits the same id five times and every reference resolves to the first one. Where the label is on the control already, drop the indirection: no attribute cannot break.
The visible words are in the name, but not at the start of it
Conformant — worth rereadingSC 2.5.3 Label in Name (Level A)
The name does contain the text on the control, so this conforms to the letter of SC 2.5.3 and we do not count it as a failure. It is reported because the understanding document for that criterion asks for the visible label at the beginning, and because of what speech input actually does: Voice Control and Dragon match a spoken phrase against the start of a name far more reliably than against the middle of one. "Read the 2026 report" wrapping a visible "Read" is conformant and still worse at the job than "Read — the 2026 report".
The fix: Reorder the name so the words on screen open it: aria-label="Send message to support" rather than aria-label="Support: send message". Nothing else about the announcement changes.
Visually hidden words pushed in front of the visible ones
Conformant — worth rereadingSC 2.5.3 Label in Name (Level A)
The control has no aria-label at all — it is named by its own contents, which is normally the safe answer. But some of those contents are in a visually-hidden span (sr-only, visually-hidden, screen-reader-text) emitted BEFORE the words on screen, so the name begins with something nobody can see. "Read more about pricing" built as a hidden "Read more about " plus a visible "pricing" is announced well and cannot be spoken by its visible word. It conforms, and it is the most common way a well-intentioned pattern degrades speech input.
The fix: Put the visible words first and the hidden qualifier after: <a>Pricing<span class="sr-only"> — read more</span></a>. Same announcement, and the spoken phrase now matches the start of the name.
The name is the opening words of a longer visible block
Conformant — worth rereadingSC 2.5.3 Label in Name (Level A)
The control wraps several phrases — a heading, a line of body copy, a call to action — and its name is the first of them, word for word. Whether this conforms depends on what a human would call "the label", and for a composite control that is genuinely arguable: the heading is what a speech-input user would say, and naming the control with it is usually the right call. It is reported because the alternative reading is also real, and because the pattern is the one that hides a genuine truncation — a name of "Send" on a control reading "Send message to support" has the same shape and is a worse answer.
The fix: Nothing, if the first phrase is the label and the rest is supporting copy — this is the conventional pattern and the reason it is not counted as a failure. If the words after it are part of what somebody would say aloud, extend the name to include them.
Field labelled only by a placeholder, named something else
Conformant — worth rereadingSC 2.5.3 Label in Name (Level A) · SC 3.3.2 Labels or Instructions (Level A)
This field has no <label> element. The only words anybody can see are its placeholder, and an aria-label gives it a different name. Whether a placeholder counts as a visible label under 2.5.3 is genuinely argued both ways, which is why this sits in the review band rather than the failure band — but the practical outcome is not arguable: the user sees one phrase, the control answers to another, and the moment they type, the phrase they were reading disappears. The underlying defect is 3.3.2, not this criterion.
The fix: Give the field a real <label>, visible, with the same words as the placeholder — then delete the placeholder or make it an example value rather than a label. A field whose only label vanishes on first keystroke has a problem no aria attribute fixes.
No controls in the HTML this server sent
Verify by handWe read the markup your server returned and found no buttons, links or form fields in it — so the page builds its interface in the browser. Nothing here is evidence of a pass: the comparison this tool makes needs the control and its name to exist in the document, and on this page neither does yet. Every finding it would have made is still possible in the rendered page.
The fix: Run the site-wide scan, which loads each page in a real browser and reads the interface after JavaScript has built it.
Questions
- My accessibility scan says these buttons pass. Why does this one disagree?
- Because they are checking a different criterion. Every name checker in existence — axe, Lighthouse, WAVE, ours included — asks "does this control have an accessible name?" That is SC 4.1.2, and a button reading "Send" with aria-label="Submit" answers yes: it has a name, it is announced, it passes. SC 2.5.3 Label in Name asks a second question nothing else asks: is the name the same as the word on it? The two criteria are both Level A, and a control can satisfy one by breaking the other. Adding an aria-label is the usual way it happens.
- Who is actually harmed by this? Screen readers announce the aria-label fine.
- Speech input. Somebody using Voice Control on iOS or macOS, Dragon on Windows, or Windows Speech Recognition drives the page by reading it aloud — they look at the button, say "click Send", and the software matches that phrase against accessible names. When the name is "Submit" the command matches nothing. There is no error and no feedback; the control simply does not respond, and the only name that would work exists in an attribute that renders as nothing. It also hits anybody using a screen reader WITH the screen — low-vision magnifier users and many dyslexic users — who hear one word and read another and have to work out which is real.
- Is a longer aria-label allowed, or does the name have to match exactly?
- Longer is allowed and often correct. The criterion says the name must CONTAIN the visible text, not equal it, so aria-label="Send message to support" on a button reading "Send" conforms — and this checker reports it as clear. What it will not accept is a name that drops the visible words: "Submit", "Contact form", "Link". The understanding document asks for the visible label at the START of the name, and there is a practical reason beyond conformance — Voice Control and Dragon match a spoken phrase against the beginning of a name far more reliably than against the middle. Names that bury the label are reported in the review band, not as failures.
- Does case, punctuation or an icon count?
- No. "Sign Up" and "Sign up" are the same label. So are "Search" and "Search…". An icon is not text and is skipped, as are decorative arrows — a link reading "Domains ↗" whose name is "Domains" is correct, and treating that arrow as a word was the single biggest source of false accusations while this tool was being built. A leading numeric badge is skipped too: a video card painted "1:31 Starship test flights" and named "Starship test flights. 00:01:31" is fine, because the chip is metadata rendered first, not part of what anybody says out loud.
- What about a button with only an icon in it?
- Out of scope here, and it needs fixing somewhere else. SC 2.5.3 applies to controls that have a visible text label; an icon-only button has none, so there is nothing to compare. It has its own Level A problem — it is announced as "button" and nothing else — and that is SC 4.1.2. The SVG checker and the button checker read those.
- Why did you report a control that has no aria-label at all?
- Because the name is built from the contents, and the contents can include words nobody can see. A link built as <span class="sr-only">Read more about </span>Pricing is announced as "Read more about Pricing" and reads on screen as "Pricing" — so the spoken word is in the name, but not at the start of it, and speech input matches it poorly. It conforms. It is reported because it is the most common way a well-intentioned pattern quietly degrades, and the fix is to move the hidden span after the visible word rather than before it.
- You skipped some of my controls. Which ones, and why?
- Four kinds. A control with no visible text — an icon-only button. A control wrapping more than eighty characters of text, because at that size "the label" is a card heading rather than a label and demanding that the name contain every word in the card invents failures out of correct pages. A control whose every child is aria-hidden, which has no accessible name at all and is a 4.1.2 finding. And a control named by an aria-labelledby pointing at an element that is empty in the HTML, which is almost always filled by JavaScript and cannot be read from here. The count of controls set aside is reported with the result rather than folded into a pass.
- Is this a WCAG 2.0 criterion? We are only committed to 2.0 AA.
- No — SC 2.5.3 arrived in WCAG 2.1, at Level A. That distinction is worth checking against what you are actually committed to. EN 301 549, which the European Accessibility Act references, requires WCAG 2.1 AA. The ADA Title II rule adopted in 2024 names WCAG 2.1 AA. Section 508 still references 2.0 AA, so this one is outside it. If your VPAT says "WCAG 2.0" and your customers are European or are US public entities, the gap between those documents is the finding, not this page.
- How did you read this without running my page?
- We read the HTML your server sent and computed the accessible name the way a browser does: aria-labelledby first, then aria-label, then the element's own contents with aria-hidden subtrees removed and visually-hidden ones kept, and the value attribute for submit buttons. Everything that needs a rendered page is outside it — text drawn into an image, a label injected by CSS content, a name attached after hydration. Nothing here is a guess about those; a page with no controls in its HTML gets an honest "cannot tell from here" rather than a pass.
- Does this replace a real audit?
- No. It reads one page, and it reads the wiring rather than the wording — whether the name contains the label, not whether either is any good. "Click here" matching "Click here" is perfectly conformant on this criterion and useless on two others. The site-wide scan renders every page in a real browser and names every WCAG violation by criterion with the failing element on the page it is on.
The rest of what a control owes somebody
A control with no name at all fails differently — the button checker reads those, and an icon with nothing to announce is the SVG checker’s business. A field whose label is not wired to it at all is the form label checker, a link whose text says nothing is the link text checker, and because controls ship from a shared component, the full WCAG scan is what tells you which of your pages that component never reached.