# Buttons must have discernible text

> Canonical HTML version: https://rocketvalidator.com/accessibility-validation/axe/4.11/button-name
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

When a button lacks an accessible name, assistive technologies like screen readers can only announce it generically — for example, as "button" — with no indication of its purpose. This is a critical barrier for people who are blind or deafblind, as they rely entirely on programmatically determined names to understand and interact with interface controls. A sighted user might infer a button's purpose from an icon or visual context, but without a text-based name, that information is completely lost to assistive technology users.

This rule maps to **WCAG 2.0, 2.1, and 2.2 Success Criterion 4.1.2: Name, Role, Value (Level A)**, which requires that all user interface components have a name that can be programmatically determined. It is also covered by **Section 508**, **EN 301 549 (9.4.1.2)**, and **Trusted Tester guidelines**, which require that the purpose of every link and button be determinable from its accessible name, description, or context.

## How to fix it

Ensure every `<button>` element or element with `role="button"` has an accessible name through one of these methods:

1. **Visible text content** inside the button element.
2. A non-empty **`aria-label`** attribute that describes the button's purpose.
3. An **`aria-labelledby`** attribute that references an element containing visible, non-empty text.
4. A **`title`** attribute (use as a last resort, since `title` tooltips are inconsistently exposed across devices).

If a button is purely decorative and should be hidden from assistive technologies, you can assign `role="presentation"` or `role="none"` and remove it from the tab order with `tabindex="-1"`. However, this is rare for interactive buttons.

### Common mistakes to avoid

- Leaving a `<button>` element completely empty.
- Using only a `value` attribute on a `<button>` — unlike `<input>` elements, the `value` attribute on `<button>` does not provide an accessible name.
- Setting `aria-label` to an empty string (`aria-label=""`).
- Pointing `aria-labelledby` to an element that doesn't exist or contains no text.
- Using only an icon or image inside a button without providing alternative text.

## Examples

### Incorrect: empty button

```html
<button id="search"></button>
```

A screen reader announces this as "button" with no indication of its purpose.

### Incorrect: button with only a `value` attribute

```html
<button id="submit" value="Submit"></button>
```

The `value` attribute does not set the accessible name for `<button>` elements.

### Incorrect: empty `aria-label`

```html
<button id="close" aria-label=""></button>
```

An empty `aria-label` results in no accessible name.

### Incorrect: `aria-labelledby` pointing to a missing or empty element

```html
<button id="save" aria-labelledby="save-label"></button>
<div id="save-label"></div>
```

The referenced element exists but contains no text, so the button has no accessible name.

### Correct: button with visible text

```html
<button>Submit order</button>
```

### Correct: icon button with `aria-label`

```html
<button aria-label="Close dialog">
  <svg aria-hidden="true" focusable="false">
    <use href="#icon-close"></use>
  </svg>
</button>
```

The `aria-label` provides the accessible name, while `aria-hidden="true"` on the SVG prevents duplicate announcements.

### Correct: button labeled by another element

```html
<h2 id="section-title">Shopping cart</h2>
<button aria-labelledby="section-title">
  <svg aria-hidden="true" focusable="false">
    <use href="#icon-arrow"></use>
  </svg>
</button>
```

The button's accessible name is drawn from the referenced heading text.

### Correct: button with `aria-label` and visible text

```html
<button aria-label="Search products">Search</button>
```

When both `aria-label` and inner text are present, `aria-label` takes precedence as the accessible name. Use this when you need a more descriptive name than what the visible text alone conveys.

### Correct: button with `title` (last resort)

```html
<button title="Print this page">
  <svg aria-hidden="true" focusable="false">
    <use href="#icon-print"></use>
  </svg>
</button>
```

The `title` attribute provides an accessible name, but visible text or `aria-label` are preferred because `title` tooltips may not be available to touch-screen or keyboard-only users.
