A11y Patterns
All patterns
Pattern

Button

The basic interactive component that triggers an action

Related WCAG criteria — click to view details

01 — Code

Code example

Baseline (HTML)tsx
Loading...
02 — Rules

Common baseline

Applies to all design systems
Must5
  • Keyboard accessible

    Must be focusable with Tab and activatable with Enter or Space.

  • Clear label

    Must have text or an aria-label that describes the button's purpose.

  • Focus indicator

    A visible focus ring must appear when the button receives keyboard focus.

  • Color contrast 4.5:1

    Text and background must meet a minimum contrast ratio of 4.5:1.

  • Communicate disabled state

    Use aria-disabled or the disabled attribute to indicate an inactive state.

Should3
  • Loading state announcement

    Provide aria-busy="true" and a screen-reader-friendly loading message.

  • Icon button label

    Buttons with only an icon must have an aria-label.

  • 44×44px touch target

    Ensure a minimum 44×44px touch target on mobile.

Avoid2
  • Do not implement buttons with div/span

    <div onClick> has no keyboard accessibility. Use <button> instead.

  • Do not distinguish state with color alone

    Do not rely solely on color to indicate active/inactive state.

03 — Implementations

Design system implementations

Additional checks

  • Handle aria-busy for loading state

    Add aria-busy="true" to a loading button and apply aria-hidden to the CircularProgress so screen readers do not announce the spinner.

  • Verify contrast for outlined variant

    The border color of the outlined variant must meet a minimum 3:1 contrast ratio against the background. Verify this in the default theme.

  • Check role when using component="a"

    Using the component prop to render an <a> makes it a link, not a button. Keep component="button" for actions; use <a> only for navigation.

Code sample

MUI Buttontsx
Loading...

Implementation notes

  • MUI Button renders a <button type="button"> element by default.
  • The disabled prop removes focus from the tab order. Use aria-disabled only if you need to keep focus on the element.
  • Avoid component="a" for non-navigation actions — it changes the semantic meaning from button to link.
  • Use sx={{ minHeight: 44 }} to meet the WCAG 2.5.5 touch target size requirement.
04 — References

References