Buttons

Buttons trigger actions. Learn how to build, style, and name buttons so they stay usable by everyone.

Overview

Buttons are user interface elements that activate a feature or trigger an action. Contrast this with links, which are designed to navigate you to a new place or new content.

For every button, three things need to be true: the right element is used, the button looks interactive, and the button has a meaningful name. For more on the principles behind these checks, as well as guidance on when to use a button rather than a link, see Links and buttons.

Why?

Buttons are a fundamental building block of our products, so even small implementation problems can be felt across every page. For screen reader assistive technology, links and buttons are expected to function differently from each other. If a button is activated and does not do what was expected, that can be disorienting and frustrating.

A common way a screen reader might navigate a page is by going through a list of all the buttons on the page, where the name is the only clue to what each button does. Without a meaningful name, a label like "OK" or an unlabeled icon is not helpful.

People who cannot perceive the visual design rely on a button's semantics and name, so a control that only looks like a button, without the underlying button element, can be missed or misused.

How to test buttons

Functionality and purpose

A button's function is to activate an action, such as submitting a comment, saving a resource, or opening a dialog. If instead the control navigates to a different page or new content, use a link. Learn when to use a link or button.

Buttons should use the button element wherever possible. ARIA constructs that recreate a button on another element do not meet all accessibility and usability needs. Learn why the semantic button element matters.

Naming

A button's purpose must be clear from its name alone. A meaningful name describes the action that occurs when the button is activated (for example: removing a list item), and the action's associated context (for example: the specific item to be removed). Keep names as succinct as possible while staying descriptive and unique.

When reviewing buttons on a page, make sure the following are true:

For more on what makes a name meaningful, with examples in code, see Meaningful and unique names below.

Visual distinction & contrast

A button should look interactive. Give buttons padding and a background color that is distinct from the background they sit on, and confirm that the button text meets WCAG 1.4.3 contrast against the button's background. Buttons also need a visible focus state and a hover state for pointer devices. Don't rely on color alone to differentiate buttons, since visual schemes such as danger or primary are not conveyed to screen readers. Learn more about button visuals.

Guidelines

For designers

  • Give buttons a shape that reads as interactive: padding with a background distinct from the surrounding area.
  • Don't rely on color alone to convey a button's meaning or hierarchy; pair a scheme such as danger with a clear text label.
  • When including an unlabeled, icon-only button in a design, recommend an accessible name.
  • When including multiple buttons that perform the same function in a design, use the same label for each.

For engineers

  • Use the Primer Button component and don't remove its focus styles.
  • Use the button element rather than an ARIA construct on another element.
  • When a button doesn't have a visible label (for example: an IconButton), provide an accessible name. Refer to ARIA 14: Using aria-label to provide an invisible label where a visible label cannot be used.
  • Because aria-label doesn't supplement visible labels but rather supplants them, when a button has a visible label, include that label in its accessible name. A good practice is to have the text of the label at the start of the name.
  • Don't use aria-label when its content would be identical to a button's visible label.
  • Don't reuse the same (visible) label or (invisible) name for buttons which perform different actions.
  • Follow the disabling guidance for links and buttons, which includes never disabling a form submit button. For the Button component's inactive and loading states, see Button component accessibility.

Common mistakes

  • Using an element that only looks like a button instead of the button element, so the control behaves unexpectedly for keyboard and assistive technology users.
  • Relying on an icon or color alone to convey a button's purpose.
  • Reusing one generic name (for example: "OK") or icon glyph across multiple buttons that perform different actions.

Examples

Do
<button type="button">
  OK
</button>
The button does not have a redundant aria-label attribute.
Don’t
<button type="button" aria-label="OK">
  OK
</button>
The button has a redundant and unnecessary aria-label attribute.
Do
<button type="button" aria-label="smockle’s profile">
  <img alt="smockle" src="https://avatars.githubusercontent.com/u/3104489?s=32">
</button>
The button should have an accessible name.
Don’t
<button type="button">
  <img src="https://avatars.githubusercontent.com/u/3104489?s=32">
</button>
The button should not be missing a name.

Meaningful and unique names

Each button in the example below has a unique name which describes its action (“Remove”) and its action’s context (for example: “'Apples'”).

<script>
  function removeItem(event) {
    const item = event.target.closest("li");
    item?.parentNode.removeChild(item);
  }
</script>
<ul>
  <li>Apples <button onclick="removeItem(event)" aria-label="Remove 'Apples'" type="button">❌</button></li>
  <li>Bananas <button onclick="removeItem(event)" aria-label="Remove 'Bananas'" type="button">❌</button></li>
  <li>Cantaloupes <button onclick="removeItem(event)" aria-label="Remove 'Cantaloupes'" type="button">❌</button></li>
</ul>

Although each button in the example below performs a different action, they all have the same name: ❌ (“cross mark”). This name does not describe the action that occurs when a given button is activated, nor does it describe the action’s context.

<script>
  function removeItem(event) {
    const item = event.target.closest("li");
    item?.parentNode.removeChild(item);
  }
</script>
<ul>
  <li>Apples <button onclick="removeItem(event)" type="button">❌</button></li>
  <li>Bananas <button onclick="removeItem(event)" type="button">❌</button></li>
  <li>Cantaloupes <button onclick="removeItem(event)" type="button">❌</button></li>
</ul>

Additional resources

Terminology: “label” vs “name”

When you review the Web Content Accessibility Guidelines (WCAG) below, you’ll encounter the terms “label” and “name”. Here are the definitions given for each:

  • label:

    text or other component with a text alternative that is presented to a user to identify a component within Web content

  • name:

    text by which software can identify a component within Web content to the user (Note: This is unrelated to the name attribute in HTML.)

The name may be hidden and only exposed by assistive technology, whereas a label is presented to all users. In many (but not all) cases, the label and the name are the same.

Identifying GitHub comments

When a button is associated with a specific comment, a comment indentifier should be included within the button’s name. reaction_target_identifier (only accessible to GitHub staff) uses aria-label-date (only accessible to GitHub staff) to generate a concise, unique comment identifier.

For example, reaction_target_identifier could be used in a reply-to-comment button’s name. In all cases, reaction_target_identifier adds the comment’s author and timestamp; conditionally, as needed, reaction_target_identifier adds progressively-verbose date information:

  • Reply to benjiallen, 2:45PM today
  • Reply to benjiallen, 2:45PM yesterday
  • Reply to benjiallen, 2:45PM on November 19
  • Reply to benjiallen, 2:45PM on November 19, 2021