Probeo
probeo

Buttons and Links Missing Accessible Names

Buttons and links without accessible names are invisible to screen readers and keyboard navigation. This page explains the accessible name computation and how to resolve unnamed interactive elements.

Interactive elements require a computed accessible name so assistive technology can identify them. Browsers calculate this name from a defined sequence: text content, then aria-label, then aria-labelledby, then title attribute. When none of these sources produce a string, the element has no name. Screen readers announce it as an unlabeled button or link. Keyboard users encounter a focusable element with no indication of what it does. The two most common violations — button-name and link-name — share this root cause.

What's wrong

One or more buttons or links on the page have no accessible name. The browser's accessible name computation evaluated all available sources — text content, aria-label, aria-labelledby, and title — and produced an empty string. The element exists in the DOM and receives focus, but assistive technology cannot describe it. Screen readers announce 'button' or 'link' with no additional context.

Why it matters

An unnamed interactive element is functionally invisible to anyone not using a pointing device. Screen reader users hear 'button' with no label and must guess what the control does. Keyboard users tab to a focused element with no description. Voice control users cannot target the element by name. This affects WCAG 4.1.2 (Name, Role, Value), a Level A success criterion. Level A failures affect the widest population of users and represent the baseline expectation for interactive content.

How browsers compute an accessible name

The accessible name computation follows a defined priority order. The browser first checks aria-labelledby, which references other elements by ID and concatenates their text. If absent, it checks aria-label, a string attribute on the element itself. If neither attribute exists, the browser uses the element's text content — the flattened string of all descendant text nodes. If text content is empty (common with icon-only buttons), it falls back to the title attribute. When all sources are empty, the computed name is an empty string. The element is unnamed.

Patterns that produce unnamed elements

  • Icon-only buttons: A <button> containing only an <svg> or <i> element with no text, aria-label, or sr-only span. This is the most frequent cause of button-name violations.
  • Image links: An <a> wrapping an <img> where the image has no alt text and the link has no other text content.
  • Empty links: An <a href> with no text content, often used for wrapping a clickable area around a block element.
  • Generated controls: JavaScript-rendered buttons where the label depends on data that fails to load or arrives after the accessibility tree is built.
  • CSS-hidden text: A button with text moved offscreen via CSS (e.g., text-indent: -9999px) that is removed from the accessibility tree by display:none or visibility:hidden on the text container.

The correct change

Every interactive element must resolve to a non-empty accessible name through at least one computation source. For icon-only buttons, add an aria-label attribute that describes the action: <button aria-label="Close dialog">. For image links, set meaningful alt text on the contained image. For empty links, add visually hidden text using a CSS class that keeps the text in the accessibility tree (position: absolute, clip, overflow: hidden) or add aria-label. The end state is that every button and link on the page announces its purpose when encountered by assistive technology.

Scope

This condition applies at the page level. Each page is evaluated independently for unnamed interactive elements. Buttons and links in shared templates, navigation, and footers propagate unnamed elements across every page that includes them. Fixing a shared component resolves the violation wherever it appears.

How to verify

  • Validation confirms the condition is resolved:
  • • Every <button> element has a non-empty computed accessible name
  • • Every <a> element with href has a non-empty computed accessible name
  • • Elements with role="button" or role="link" have a non-empty computed accessible name
  • • Icon-only buttons include aria-label or visually hidden text
  • • Image links have alt text on the contained image or aria-label on the link
  • • Browser accessibility inspector shows a name for each interactive element
  • • Screen reader announces each button and link with a descriptive label

Takeaway

  • Interactive elements without accessible names cannot be identified by assistive technology
  • The accessible name computation follows a strict priority: aria-labelledby → aria-label → text content → title
  • Icon-only buttons are the most common source of this violation
  • Fixing shared components eliminates the violation across all pages that use them

FAQ

How do I label an icon-only button?
Add aria-label to the button element with a description of the action, not the icon. A magnifying glass button is labeled 'Search', not 'Magnifying glass'. Alternatively, include a visually hidden <span> with the label text inside the button. Both approaches produce a computed accessible name without changing the visual design.
Does the title attribute work as a fallback?
Technically yes — it is the last source in the name computation. In practice, title is unreliable. Screen readers do not consistently announce it. It is invisible to touch device users. It creates a tooltip that may obscure content. Use aria-label or text content instead. Reserve title for supplementary information, not as the primary name source.
How should SVG links be labeled?
If an <a> wraps an SVG with no text, add aria-label to the link. Setting role='img' and aria-label on the SVG itself does not reliably propagate to the link's computed name across all browser and screen reader combinations. The link element needs its own accessible name.
What is the difference between aria-label and aria-labelledby?
aria-label is a string value on the element itself. aria-labelledby references one or more other elements by ID and uses their text content as the label. aria-labelledby takes precedence in the name computation. Use aria-labelledby when a visible label already exists elsewhere on the page. Use aria-label when the label needs to exist only in the accessibility tree.
Can CSS-hidden text provide an accessible name?
Only if the hiding technique keeps the text in the accessibility tree. The common 'sr-only' or 'visually-hidden' class pattern (position: absolute, width: 1px, height: 1px, overflow: hidden, clip) works correctly. display:none and visibility:hidden remove the text from the accessibility tree entirely. Those styles make the text invisible to both sighted users and screen readers.
Do placeholder attributes count as accessible names for buttons?
No. Placeholder is defined for input elements, not buttons or links. Even on inputs, placeholder does not reliably serve as an accessible name. It disappears when the user types, and some assistive technology does not treat it as a label. Use a <label> element for inputs and aria-label or text content for buttons and links.