button-name-present

Buttons have an accessible name

automaticWCAG 4.1.2 (A)confidence: highseverity: seriousrobust

Checks that buttons expose a non-empty accessible name.

Applies to. Applies to <button>, <input type="button">, <input type="submit">, <input type="reset"> and elements whose role attribute resolves to button (its first known, non-abstract token, in any case, so role="foo button" counts and role="link button" does not), where the element is included in the accessibility tree. role="presentation"/"none" takes an element out of scope unless a global ARIA attribute or focusability restores its role, per presentational roles conflict resolution. A custom element whose ElementInternals give it the button role (this.attachInternals().role), with no role attribute naming another, counts as a native element with that role does.

Expectation. The element has a non-empty accessible name. A programmatic name is taken first (aria-labelledby, aria-label, an associated <label>, title). Failing that, an <input> button falls back to its value attribute, and type="submit"/type="reset" fall back to the user agent's own "Submit"/"Reset" default, which is why those two are never nameless. Failing both, a button whose role is name-from-content falls back to its subtree text, counting each descendant's own name (an <img alt>, aria-label, an <svg>'s <title> child, or title) rather than only text nodes.

What a finding reports.

  • refs.accessibleName: what the lookup of a programmatic name (aria-labelledby, aria-label, <label>, title) found. Its mechanism is the source it stopped at, none when there was none, and its flags say why a naming attribute that is there gave no name, for example aria-label-empty or aria-labelledby-empty-or-unresolvable.

These data.details fields help to read and reproduce a finding. Apart from reasonCode and the few fields Output schema names as stable, they are not a stable contract: a field may be renamed or dropped in a minor release, so don’t build on them.

Examples

pass
<button>Save</button>

The button's text content is its accessible name.

fail
<button></button>

The button has no text content, aria-label, or aria-labelledby.

How to check

When this rule can’t decide, it reports cantTell and leaves the question to a person. Each question it can ask is listed here under its reason code, with the steps to answer it. A finding carries the same steps as howToCheck, in the scan’s language. See Output schema.

name_closedContent

  1. Find the button the report names and note the text or icon it shows on screen.
  2. Open the Accessibility pane in the browser's developer tools and read the element's accessible name, which the browser works out from content no script can read.
  3. With a screen reader, move to the element and listen to the name announced.

Pass. The accessibility tree shows a name for the button, taken from its content, and the screen reader announces it.

Fail. The button has no name in the accessibility tree, since its content gives none, which fails WCAG 4.1.2.

name_contentTooDeep

  1. Find the button the report names and note the text it shows on screen.
  2. Open the Accessibility pane in the browser's developer tools and read the element's accessible name, which the browser works out from all of its nested content.
  3. With a screen reader, move to the element and listen to the name announced.

Pass. The accessibility tree shows a name for the button, taken from its nested content, and the screen reader announces it.

Fail. The button has no name in the accessibility tree, since its content gives none, which fails WCAG 4.1.2.

name_internals

  1. Inspect the button the report names, a custom element, and note its role.
  2. Open the Accessibility pane in the browser's developer tools and read the element's accessible name.
  3. With a screen reader, move to the element and listen to the name announced.

Pass. The accessibility tree shows a name for the button, set through its internals or otherwise, and the screen reader announces it.

Fail. The button has no name in the accessibility tree and the screen reader announces only its role, which fails WCAG 4.1.2.

View source