Buttons are one of the most common interactive elements on the web. Making them accessible ensures that all users can interact with your interface effectively.

Why Accessible Buttons Matter

Buttons are fundamental to web interaction, and their accessibility directly impacts how users navigate and complete tasks on your website. When buttons aren’t accessible, they create barriers that can prevent users from accomplishing their goals.

For keyboard-only users: Buttons must be focusable and operable using only the keyboard. Users with motor impairments often rely on keyboard navigation, and inaccessible buttons can completely block their ability to interact with your site.

For screen reader users: Buttons need clear, descriptive text that explains their purpose. Without proper labeling, screen reader users won’t understand what a button does or when it’s appropriate to use it.

For users with visual impairments: Buttons need sufficient color contrast and clear focus indicators. Users with low vision need to be able to see where they are on the page and what elements are interactive.

For users with motor impairments: Buttons need to be large enough to click or tap easily. The WCAG guideline of 44x44 pixels minimum touch target size ensures buttons are usable for people with tremors or limited dexterity.

For users with cognitive disabilities: Clear, consistent button labeling helps users understand what will happen when they click. Ambiguous or inconsistent button text can cause confusion and anxiety.

The Impact of Inaccessible Buttons

When buttons aren’t accessible, they create significant problems:

  • Keyboard users might not be able to access important functionality at all
  • Screen reader users might not understand what buttons do, leading to confusion and errors
  • Users with motor impairments might not be able to click buttons that are too small
  • All users might become frustrated and abandon tasks if buttons don’t work as expected

This is why WCAG 2.1.1 (Keyboard) and 2.4.7 (Focus Visible) specifically address button accessibility requirements.

Basic Accessible Button

The simplest way to create an accessible button is to use the semantic <button> element:

<button type="button" class="btn btn-primary">
  Submit Form
</button>

Why this works:

  • Semantic HTML provides built-in accessibility - the browser automatically makes it focusable, keyboard-accessible, and announces it as a button to screen readers
  • Keyboard accessible by default - users can Tab to it and activate it with Enter or Space, essential for users who can’t use a mouse
  • Screen readers announce it as a button - this helps users understand the element’s purpose and how to interact with it
  • Focusable and clickable - the button receives focus naturally in the tab order and responds to both mouse and keyboard input
  • Built-in form handling - when used in forms, the button type determines its behavior (submit, reset, or button)

Button with Icon

When adding icons to buttons, ensure the icon doesn’t interfere with accessibility:

<button type="button" class="btn btn-icon" aria-label="Close dialog">
  <svg aria-hidden="true" focusable="false" width="16" height="16">
    <path d="M4 4l8 8m0-8l-8 8"/>
  </svg>
</button>

Key accessibility features:

  • aria-label provides the button’s purpose to screen readers - since the icon alone doesn’t convey meaning, the aria-label ensures screen reader users understand the button’s function
  • aria-hidden="true" hides the icon from screen readers - prevents redundant announcements since the aria-label already describes the button’s purpose
  • focusable="false" prevents the SVG from receiving focus - ensures only the button itself is focusable, not the decorative icon inside it
  • Semantic button element - maintains all the built-in accessibility features of a native button while adding the visual icon

Submit and Reset Buttons

For form buttons, use appropriate types:

<button type="submit" class="btn btn-primary">
  Save Changes
</button>

<button type="reset" class="btn btn-secondary">
  Reset Form
</button>

Loading State Button

For buttons that trigger loading states:

<button type="button" class="btn" aria-busy="true" aria-live="polite">
  <span class="spinner" aria-hidden="true"></span>
  Processing...
</button>

CSS for Accessible Buttons

Proper styling ensures buttons are visually accessible:

.btn {
  padding: 0.5rem 1rem;
  border: 2px solid transparent;
  border-radius: 0.25rem;
  font-size: 1rem;
  cursor: pointer;
  min-height: 44px; /* WCAG touch target size */
  transition: all 0.2s ease;
}

.btn:focus {
  outline: 2px solid #0062FF;
  outline-offset: 2px;
}

.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* Loading state */
.btn[aria-busy="true"] {
  position: relative;
  color: transparent;
}

.btn[aria-busy="true"]::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  border: 2px solid transparent;
  border-top: 2px solid currentColor;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

Common Button Patterns

Toggle Button

<button type="button" aria-pressed="false" aria-label="Toggle notifications">
  <svg aria-hidden="true">
    <!-- bell icon -->
  </svg>
</button>
<button type="button" aria-expanded="false" aria-haspopup="true" aria-label="Open menu">
  Menu
  <svg aria-hidden="true">
    <!-- dropdown arrow -->
  </svg>
</button>

Remember: The key to accessible buttons is using semantic HTML, providing clear accessible names, ensuring keyboard accessibility, and maintaining sufficient visual contrast.