Cmpnts

Menu

Atoms

Button

An action on the page, such as saving a Form, opening a Dialog or changing a setting.


Code
HTML
<button type="button" class="button"><span>Save changes</span></button>

Why it exists

Most of what a person does on a page, they do through a Button. It is a real <button> because the browser already gives it focus, keyboard use and a role that assistive technology understands, and nothing here replaces those.

Its look comes from two separate choices: prominence says how much attention an action deserves, and intent says what kind of action it is. Keeping them apart means a quiet destructive action and a loud one are the same two ideas, not two more variants to learn.

A 48px hit area is the default at every size, because a target that’s easy to reach helps everyone. A smaller one is a decision a product makes on purpose.

When to use

  • For an action: submit, save, open, delete, toggle. Use <button type="button"> (or type="submit" in a Form).
  • Not for going somewhere. A Link goes to another page, even when it looks like a Button: <a class="button"> keeps its link role.
  • Not for one choice among views (a Tab List) or a setting that is on or off (a switch), unless it is a toggle Button.

Rules

  • Never colour alone (WCAG 1.4.1): the label says what happens (“Delete project”), or an icon does.
  • Every size keeps a 48px hit area (WCAG 2.5.5), unless the product opts into fine-pointer targets. Never below 24px (2.5.8).
  • One modifier per axis. Write .button--subtle.button--accent. A class that fuses two axes doesn’t exist.

Keyboard and screen readers

  • Enter and Space both press a Button. The browser handles this, so don’t add key handlers.
  • Tab reaches it, in reading order. Don’t change that with a positive tabindex.
  • A toggle says its state through aria-pressed, so a screen reader announces “pressed”. Keep the label the same in both states.
  • A disabled Button can’t be focused, so nobody using a keyboard can discover why it’s disabled. Say why near it.

Icons

Code
HTML
<button type="button" class="button button--strong button--accent">
  <span>Get started</span>
  <svg class="icon icon--dir" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="#ArrowRight"/></svg>
</button>
<button type="button" class="button">
  <svg class="icon" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="#Plus"/></svg>
  <span>Add record</span>
</button>
<button type="button" class="button button--icon">
  <span class="sr-only">Search site</span>
  <svg class="icon" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="#Search"/></svg>
</button>
<button type="button" class="button button--plain button--icon button--round">
  <span class="sr-only">More actions</span>
  <svg class="icon" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="#More"/></svg>
</button>
  • Icon-only Buttons keep a text label in .sr-only, so screen readers, translation and voice control (“click Search site”) all have a name. The icon is aria-hidden.
  • .icon--dir mirrors an arrow in right-to-left text.
  • --labeled keeps the text when a container hides Button labels (--ui-labels: hidden).
  • An Avatar in a Button: a plain round icon Button holding a hidden Avatar.

Toggles and Choices

Code
HTML
<button type="button" class="button" aria-pressed="true"><span>Bold</span></button>
<label class="button">
  <input type="checkbox" class="sr-only" />
  <svg class="icon icon--off" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="#Close"/></svg>
  <svg class="icon icon--on" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="#Check"/></svg>
  <span>Notifications</span>
</label>
<div class="cluster" role="radiogroup" aria-label="Delivery">
  <label class="button">
    <input type="radio" name="delivery-demo" class="sr-only" checked />
    <span>Standard</span>
    <svg class="icon icon--on" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="#Check"/></svg>
  </label>
  <label class="button">
    <input type="radio" name="delivery-demo" class="sr-only" />
    <span>Express</span>
    <svg class="icon icon--on" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="#Check"/></svg>
  </label>
</div>
  • A toggle Button takes aria-pressed; its label stays the same as it changes (“Bold”, not “Bold on”).
  • A Checkbox or radio styled as a Button is a <label class="button"> around a visually hidden input. It needs no script, and the Input keeps its keyboard and screen-reader behaviour. .icon--on and .icon--off show with the state.
Code
HTML
<a href="/start" class="button button--strong button--accent">
  <span>Read the guide</span>
  <svg class="icon icon--dir" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="#ArrowRight"/></svg>
</a>

It goes somewhere, so it stays a Link: no role="button". Screen-reader users hear “link” and expect a new page; keyboard users open it with Enter (a Button also takes Space).

Do and Don’t

DoDon’t
Start the label with a verb: “Save changes”, “Delete project”.Use “OK”, “Submit” or “Click here” when a verb would say what happens.
Use one strong accent Button per view, for the main action.Make every Button strong; nothing stands out.
Say what a danger Button destroys, in its label.Rely on red to say an action is destructive.
Give an icon-only Button a hidden text label.Leave it to title, or to the icon alone.
Use a Link, styled as a Button if you like, to go to another page.Put role="button" on a Link, or navigate from a <button> with script.
Explain near a disabled Button why it can’t be used yet.Disable a submit Button without saying what’s missing.

In Storybook

See also

  • Button Group: A set of related Buttons laid out together, in a row or a column.
  • Link and Block Link: A way to go somewhere else, in running text or as a row of its own.
  • Menu: A list of actions in rows, usually opened from a Button in a Popover.
  • Icon and Icon Box: A small glyph that helps people recognise something, on its own or in a frame.

Search the docs