# Buttons must have discernible text.

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

Every button on a page needs an accessible name that assistive technologies can announce to users. When a button has no discernible text, screen reader users hear something like "button" with no indication of what the button does. They cannot distinguish it from other buttons or understand its purpose, which makes the interface unusable for them.

This rule applies to any element with a `button` role that is included in the accessibility tree. That includes `<button>` elements, `<input>` elements with `type="submit"` or `type="reset"`, and any element with `role="button"`. The one exception is `<input type="image">`, which is covered by a separate rule related to image alternative text.

The accessible name for a button can come from several sources: visible text content inside the element, a `value` attribute (for `<input>` buttons), an `aria-label` attribute, or an `aria-labelledby` attribute pointing to another element that contains the label text. If none of these provide a non-empty string, the button fails this rule.

This maps to WCAG 2 Success Criterion 4.1.2 (Name, Role, Value) at Level A. That criterion requires all user interface components to have a name that can be programmatically determined. Buttons without accessible names violate this requirement.

Note that `<input type="submit">` and `<input type="reset">` have default accessible names ("Submit" and "Reset" respectively) defined by the HTML accessibility API mappings. These defaults satisfy the rule even without an explicit `value` attribute.

## How to fix it

The right fix depends on what kind of button you have:

- If the button contains visible text, that text becomes the accessible name automatically. Make sure the text is not empty or whitespace-only.
- If the button contains only an icon (SVG, icon font, or `<img>`), add an `aria-label` attribute that describes the action the button performs, such as `aria-label="Close"` or `aria-label="Search"`.
- If the button contains an `<img>` element, you can provide the accessible name through the image's `alt` attribute instead. The `alt` text should describe the button's action, not the image itself.
- If a visible label exists elsewhere on the page, use `aria-labelledby` to reference that element's `id`.
- For `<input>` buttons, set the `value` attribute to meaningful text.

The accessible name should describe what the button does. "Close dialog", "Submit form", and "Delete item" are good names. Avoid generic labels like "Click here" or "Button".

## Examples

### Button with no accessible name

This button has no text content, no `aria-label`, and no other source of an accessible name. A screen reader announces it as just "button."

```html
<button></button>
```

### Button with only whitespace

Whitespace alone does not count as an accessible name.

```html
<button> </button>
```

### Icon button with no label

This button uses an icon font but provides no text alternative. Screen reader users have no way to know what it does.

```html
<button>
  <i class="icon-close"></i>
</button>
```

### Fixed: button with visible text

The simplest fix is visible text inside the button.

```html
<button>Close</button>
```

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

When the button has no visible text, `aria-label` provides the accessible name.

```html
<button aria-label="Close">
  <i class="icon-close"></i>
</button>
```

### Fixed: button with an image

If the button contains an `<img>`, the image's `alt` attribute supplies the accessible name.

```html
<button>
  <img src="search.png" alt="Search">
</button>
```

### Fixed: input button with `value`

For `<input>` buttons, the `value` attribute provides the accessible name.

```html
<input type="submit" value="Send message">
```

### Fixed: button labeled by another element

The `aria-labelledby` attribute can point to an element whose text content becomes the button's accessible name.

```html
<span id="save-label">Save changes</span>
<button aria-labelledby="save-label">
  <i class="icon-save"></i>
</button>
```

### Fixed: custom element with `role="button"`

Elements with `role="button"` follow the same rules. They need an accessible name too.

```html
<span role="button" tabindex="0" aria-label="Menu">
  <i class="icon-hamburger"></i>
</span>
```
