Documentation/Buttons need accessible text

Buttons need accessible text

ZMD011

ZemDomu flags supported <button> elements whose source does not provide an accessible name through visible text, ARIA naming, or labeled descendant content.

What this rule catches

  • Empty buttons and icon-only buttons with no supported accessible-name source.
  • Supported aria-label, aria-labelledby, text, and labeled-image patterns that resolve to no usable name in the analyzed source.

What static analysis cannot prove

  • Static analysis cannot judge whether a button name clearly describes its action in context.
  • Names created by runtime state, localization, or third-party components may need rendered-DOM and screen-reader testing.

Standards classification and detection confidence

Classification
normativeThe rule checks for a source-level accessible name on a supported button.
Detection confidence
context dependentResolved visible text and ARIA naming sources are reliable evidence. Runtime labels and unresolved icon components can change the accessible name.

Applicable WCAG 2.2 criteria

Criterion 4.1.2 requires the button's name and role to be programmatically determinable.

Normative means the rule checks a machine-testable part of a cited standards requirement. Advisory means it enforces a documented authoring convention or supporting technique. Neither classification makes a ZemDomu result proof of WCAG conformance.

Examples

✅ Good

<button>Submit</button>
<button aria-label="Close"></button>
<span id="close-label">Close</span>
<button aria-labelledby="close-label"></button>
<button><img alt="Close" src="/icon.svg" /></button>

❌ Bad

<button></button>
<button aria-label=""></button>
<button aria-labelledby="missing"></button>
<button><svg></svg></button>

React and Vue notes

React/TSX
Visible JSX text and static aria-label or aria-labelledby values can provide the name; expression results may require testing in the rendered component.
Vue
Visible template text and static ARIA naming values can provide the name; names supplied only by reactive bindings may require rendered testing.

Quick summary

When: A button has an empty accessible name

Warning: <button> missing accessible text

Solution: Provide text, aria-label, aria-labelledby, or labeled content

Why it matters

Accessibility: Unlabeled buttons are announced as ‘button’ only, offering no context to screen-reader users.

SEO: Buttons aren’t indexed by search engines when they lack descriptive names.

Rule details

In brief

  • Goal: Ensure each button has a non-empty accessible name.
  • What to do: Provide text, aria-label, aria-labelledby, or labeled content (like img alt) for every <button>.
  • Why: Screen readers announce only ‘button’ when no name is provided.

Intent

Prevent unnamed buttons by enforcing reliable accessible-name sources.

Benefits

  • Clear announcements for screen-reader users.
  • Improved keyboard focus and navigation.
  • Early detection of missing names via linters.

Techniques

  • G208: Accessible Name Computation for button content.
  • ARIA6: Using aria-label to provide labels for button elements.

HTML Semantics

The <button> element's label is its accessible name; it can come from text, aria-label, aria-labelledby, or labeled descendants like img alt.

Tips & edge cases

  • Prefer visible text when possible; use aria-label or aria-labelledby when the UI is icon-only.
  • If the label lives elsewhere on the page, connect it with aria-labelledby.