button
A button lets people start something on the screen they are on: save a form, run a check, grab a release, ask the catalog again.
when to use
- To start an action on the current screen, such as “save changes”, “run” or “ask the catalog again”.
- As the one emphasized action of a view, a toolbar or a dialog. It is the step most people take next, so it is the only button filled with colour.
- Beside it, for the other actions, and for a quiet way out such as “cancel”.
when to use something else
- To go somewhere. Use a link. A button that changes the page breaks “open in new tab” and the browser's back button.
- For an icon without a label. Use an icon button, which always carries a name.
- For more than two or three actions in a row. Put them in a toolbar, and let the rest go into an action menu.
- For an action on every row of a table. Give each row one action menu, and put the actions for several rows in a selection toolbar. Selection and bulk actions shows how.
anatomy
- Frame. A square with a thin border, in one of three heights.
- Leading icon (optional). An icon before the label. While the button is busy, a spinner takes its place.
- Label. What the button does, in monospace and lowercase.
- Trailing icon (optional). An icon after the label. It steps aside while the button is busy.
variants and states
There are four kinds of button. Only the emphasized one is filled, because it marks the next step; the others stay quieter so it can stand out.
| kind | looks | use it for |
|---|---|---|
| Emphasized | Filled with blue, with a dark label | The one emphasized action of a view or a region |
| Standard | A dark fill and a thin border, which turns blue under the pointer | Every other action |
| Quiet | No fill and no border until the pointer rests on it | Cancel, dismiss and other light actions next to an emphasized one |
| Danger | An amber outline, which fills with amber under the pointer | An action that deletes something or can't be undone |
Buttons come in three heights, the same three as every other control, so a row of controls lines up. The small one suits toolbars and table rows, the medium one is the usual choice, and the large one is for a single call to action that stands on its own.
While its action runs, a button is busy: a spinner appears and further presses are ignored. Its width stays the same, so nothing around it jumps. A disabled button is dimmed and the keyboard passes over it.
An icon can sit before or after the label, and a button can stretch to the full width of its container.
behaviour
- A button acts on the current screen when it is pressed: with a click or a tap, or with enter or space on the keyboard.
- While its action runs, the button keeps its place and its label, and a second press does nothing. Afterwards, say what happened, in a toast or where the result shows.
- A disabled or busy button ignores presses.
- In a form, only the button that saves the form sends it. Every other button just does its own job.
The full keyboard map is on the button's React page.
accessibility
- A screen reader announces a button by its label. The lowercase look is only a style, so write the label exactly as it should be read.
- A disabled button can't take focus, so people who use a keyboard or a screen reader may never find it. When the reason matters, such as “nothing selected”, say it next to the button, or keep the button enabled and explain when it is pressed.
- Icons inside a button are decoration; the label carries the meaning. An action that is only an icon is an icon button.
- Keyboard focus shows as the same outline that every control uses. Interaction explains it.
content
- Start with a verb, and name the object when the screen holds more than one kind of thing: “grab 8 selected”, “ask the catalog again”, “save changes”.
- Keep the label short and lowercase, with no full stop and no exclamation mark.
- A name inside the label, such as a language or a title, keeps its capitals: “find German for 4 selected”, “open The Quiet Orchard”.
- Avoid “ok”, “submit”, “yes” and “click here”. Say what will happen instead.
- In an action for several items, include the count. “grab 8 selected” tells people more than “grab selected”.
do and don't
related
- Icon button: the same action, shown as an icon only.
- Toolbar: a row of actions, with one emphasized and the rest in a menu.
- Action menu: several actions behind one button, such as one menu per table row.
- Content & voice: how labels are written.
specs
| kind | in code | at rest | under the pointer |
|---|---|---|---|
| Emphasized | variant="primary" |
--cloud-blue fill and border, --bg label |
A lighter blue; a darker blue while pressed |
| Standard | variant="default" (the default) |
--surface fill, --border-2 border, --fg label |
--surface-2 fill and a --cloud-blue border; --bg-2 while pressed |
| Quiet | variant="ghost" |
No fill or border, --fg-2 label |
--surface-2 fill and a --fg label; --bg-2 while pressed |
| Danger | variant="danger" |
--signal-amber border and label, no fill |
--signal-amber fill and a --bg label |
| size | in code | height | side padding | label | spinner |
|---|---|---|---|---|---|
| Small | size="sm" |
28px | 12px | 12px | 12px |
| Medium | size="md" (the default) |
34px | 16px | 13px | 14px |
| Large | size="lg" |
42px | 24px | 14px | 14px |
- Frame: square (
border-radius: 0), a 1px border; icon and label 8px apart. - Label: JetBrains Mono 600, lowercased with
text-transform, on one line. A name wrapped inKeepCasekeeps its case. - Busy:
loading. A spinner in the leading slot, the trailing slot hidden, the width unchanged. The button is disabled while busy, so it ignores presses and leaves the tab order. - Disabled:
disabled. 45% opacity, a not-allowed cursor, out of the tab order. - Icons:
leadingandtrailingtake an element, such as anIcon: 12px in a small button, 16px in a medium one (see iconography). - Full width:
block. - Focus: the 2px
--focus-ringoutline, 1px outside the frame, on keyboard focus only. - Motion: background, border and label colours change in 120ms
ease.