Website Performance & Accessibility Tools

Accessible Name Debugger

Paste an HTML component and see the accessible name and description each element receives, which rule produced it, and why aria-label, labels or content lost.

  • Name and description per element
  • Rule trace
  • Failures with fixes
Runs in your browser

Everything you paste, type or drop is processed in this browser tab. It is not uploaded, logged, stored or sent to analytics.

Accessible name workspace

1 Your component

Examples:

Up to 1 MB. Parsed inertly in your browser: scripts do not run and nothing is fetched or sent.

What this can and cannot see

It follows the AccName 1.2 steps and HTML-AAM rules on the markup you paste. It cannot see CSS ::before/::after text, stylesheet rules that hide things (only the hidden attribute, aria-hidden and inline style count), text added later by script, or shadow DOM. Confirm important names in the browser's accessibility tree (DevTools, Accessibility pane).

2 Names, descriptions and rules

Paste HTML or load an example, then compute names.

What the Accessible Name Debugger does

This debugger works out the accessible name and description a browser gives each element in a piece of HTML, and shows which rule of the W3C Accessible Name computation produced it. Paste a button, a form or a whole page and you see, element by element, what a screen reader will announce, and why an aria-label, a <label> or the visible text won or lost.

The accessible name is the words assistive technology says for a control: "Delete, button", "Email, edit text". Browsers compute it with a fixed order of rules defined in Accessible Name and Description Computation 1.2 and the HTML Accessibility API Mappings. When a control sounds wrong or silent, the cause is nearly always one of those rules, and the trace here names it.

How to use it

  1. Paste the HTML of a component, or load one of the examples. The markup is parsed inertly in your browser: scripts do not run and images are not fetched.
  2. Press Compute names. Each element that can carry a name - controls, links, images, landmarks, headings, tables, dialogs, anything focusable or with ARIA - gets a row with its role, name, the rule that produced the name, and any description.
  3. Read the findings first. Problems are names that are missing where the role requires one, or references to ids that do not exist; warnings are names that exist but are fragile or mismatched.
  4. Pick an element in the trace selector to see every step the computation took for it: which steps were skipped, which were empty and which one supplied the name.
  5. Fix the markup and run it again. Export the table as CSV or JSON to attach to a ticket.

Reading the results

The From rule column uses the step numbers of AccName 1.2. 2B is aria-labelledby, 2D is aria-label, 2E is a native HTML mechanism such as <label>, alt, <legend> or <caption>, 2F is the element's own text content, and 2I is the title attribute used as a last resort. The first step that yields text wins, and every later step is ignored - which is why an aria-label silently replaces the visible text of a button.

A name coming from 2I (title) or from the placeholder fallback is flagged even though it works, because a title only appears on mouse hover and a placeholder disappears as soon as someone types. A visible label serves everyone.

The description is a separate, secondary announcement: aria-describedby first, then aria-description, then title when the title was not already used for the name. Screen readers usually read it after a pause, and some users switch descriptions off, so nothing essential should live only there.

Worked example: why the Delete button says "Delete Delete project?"

The dialog example contains <button id="del" aria-labelledby="del dlgTitle">Delete</button> next to a heading <h2 id="dlgTitle">Delete project?</h2>. Step 2B applies because aria-labelledby is present. It lists two ids: the button itself and the heading.

For the first id the computation does not follow aria-labelledby again (it is already inside that traversal), so it takes the button's own content: "Delete". For the second it takes the heading's content: "Delete project?". The parts are joined with a space, giving "Delete Delete project?" - accurate, but repetitive. Pointing aria-labelledby at the heading alone, or removing it so the name comes from content, would be clearer.

The Cancel button in the same example references missingId. No element has that id, so the reference is ignored and the name falls through to the content, "Cancel"; the tool still reports the broken reference, because a later edit could remove the text and leave the button silent.

Hidden content and aria-labelledby

Content that is hidden - with the hidden attribute, aria-hidden="true" or an inline display: none - is normally left out of names. AccName 1.2 makes one exception: if aria-labelledby or aria-describedby points directly at a hidden element, that element's text is used, including its hidden descendants. That is how a visually hidden tooltip can name an icon button. The debugger models this rule and the trace says when it was applied.

The presentational role is the other common surprise. role="presentation" or role="none" removes an element's semantics, but browsers ignore it when the element is focusable or carries a global ARIA attribute such as aria-label, and keep the native role instead. The tool reports those conflicts.

Limitations: what the result does not prove

  • It sees only the markup you paste. Text inserted by CSS ::before and ::after, elements hidden by a stylesheet rule, names changed by script after load and anything inside shadow DOM are not visible to it, so confirm important results in the browser's accessibility tree.
  • Browsers still differ on edge cases of the specification, particularly whitespace between inline elements and deeply nested embedded controls. The tool follows the specification text; a real browser may differ by a space.
  • A correct accessible name does not prove a component is accessible. Keyboard operation, focus management, states such as aria-expanded and contrast all need their own checks.
  • Default names such as "Submit" for <input type="submit"> are localised by each browser; the tool shows the English default.

Privacy: where your data goes

Everything you paste, type or drop is processed in this browser tab. It is not uploaded, logged, stored or sent to analytics. Session recording and tag-manager scripts are switched off on this page.

Standards and sources

Frequently asked questions

What is the difference between aria-label and aria-labelledby?

aria-label holds the name as a string on the element itself; aria-labelledby points at other elements by id and uses their text. aria-labelledby wins when both are present, and it is usually better because it reuses visible text that translators and sighted users also see.

Why does my button's aria-label replace its visible text?

Because step 2D (aria-label) comes before step 2F (name from content) in the computation, and the first step that produces text wins. If the visible text is "Send" and the aria-label is "Submit form", speech-input users who say "click Send" will fail. Keep the visible words at the start of the name, as WCAG 2.5.3 Label in Name requires.

Does the title attribute count as an accessible name?

Yes, but only as the last resort (step 2I), when no aria attribute, native label or text content produced anything. It is flagged here because a title is shown only on mouse hover, so keyboard, touch and many screen magnifier users never see the text that names the control.

Can a hidden element provide a label?

Yes, when it is referenced directly by aria-labelledby or aria-describedby. AccName 1.2 says a hidden node reached that way is included, together with its hidden children. Hidden text reached any other way - inside a button's content, for example - is excluded from the name.

Is placeholder text an acceptable label for an input?

The HTML accessibility mappings do fall back to the placeholder when there is no label or title, so the field is not silent. It is still a weak label: it disappears once the person types, often has low contrast, and some assistive technology treats it as a hint rather than a name. Use a visible label element.

Why is my aria-label on a span or div ignored?

A plain span or div has the role generic, and ARIA 1.2 prohibits naming generic, paragraph, emphasis and similar text-level roles. Several screen readers therefore skip the aria-label entirely. Give the element a role that supports a name, such as img or a real control, or put the words in visible text.

How is this different from the browser's accessibility inspector?

The inspector shows the final name for the live page, including CSS and script effects. This tool works on pasted markup before it ships, explains every step of the computation, checks many elements at once and exports a report. Use both: the trace to understand, the inspector to confirm.

Last reviewed by the A2Z.Tools team against the sources listed above.

Rate this tool

Was this tool useful? Your feedback helps us improve it.

No ratings yet — be the first to rate this tool.
Your rating (required)
0 / 2000

Please do not include passwords, payment details or other sensitive information.

Your feedback is sent privately to the A2Z.Tools team and will not be posted publicly.