A button that stays on or off, such as bold text, a map layer or a filter: the outline or ghost button when off, sunken into the page when on.
Options
| Choice | Values | Default | What it does |
|---|---|---|---|
tonesmbk-btn--tone-<value> | outlineghost | outline | How it looks when off: the outline button, or the ghost button with no fill or edge, for a tool among others in a toolbar. On looks the same in both. Figma draws the outline toggle; the ghost one is the toolbar’s tool. |
sizesmbk-btn--size-<value> | lgmdsm | md | The button’s own heights, padding, label and icon, one recipe per height. md fits apps and forms. |
icon-onlysmbk-btn--icon-only | On or off | Off | A square toggle holding one icon and no label, for a toolbar. Needs an accessible name. |
Examples
Usage
A setting that applies at once and stays until pressed again, here switched on.
On and off
Off is the outline button; on sinks into the page, with the same size, so nothing moves.
Sizes
The button’s three heights, 48, 40 and 32, with its padding and label.
With an icon
An icon before the words, as on the button.
Icon only
A square toggle with one icon, for a toolbar. Its name stays the same on and off; the pressed state says which.
Ghost
The ghost tone, for a tool among others in a toolbar: off it has no fill or edge, on it sinks in as the outline toggle does.
Guidelines
Purpose
A button that stays on or off: bold text in an editor, a layer on a map, a filter that is applied. Pressing it switches a setting rather than running a one-off action, and it shows which way the setting is. It differs from the switch, which sets an option in a form or a settings list, and from the segmented control, which picks one of several choices.
When to use
- A setting that applies at once and stays applied until pressed again: bold, a grid overlay, a map layer, "Show archived".
- A tool in a toolbar that is either on or off.
When not to use
- An option in a form or a settings list that is saved with the form. Use the switch, or a checkbox.
- One choice out of several. Use the segmented control or radios.
- A one-off action. Use the button.
Usage rules
Do
- Name it for the setting it switches, the same in both states.
- Group related toggles together, such as bold, italic and underline.
Don't
- Change its label when it is pressed. The pressed state says it.
- Use it for a choice saved with a form. Use the switch or a checkbox.
Name it for the setting, the same on and off; the pressed state says which.
A label that changes when pressed makes the reader work out which state it is in.
Anatomy
- The block,
smbk-toggle-button, on a button with the outline button's look when off, or the ghost button's for a tool among others in a toolbar. The markup has the toggle's block, then the button's own classes, at the chosen tone and size. The button's stylesheet draws it, off and on. - The label part and the icon part, the button's own: words, an icon before them, or an icon alone.
Being on is the button's pressed state, read from its markup; there is no class for it, so what the reader sees and what a screen reader hears always agree.
Behavior
Off, it is the outline button, or the ghost button in the ghost tone, with the same hover and pressed looks. On, it sinks into the page: the sunken fill, a soft shadow along its inner top edge and a light rim for its edge. It keeps the same size on and off, so nothing around it moves. Hovering an on toggle keeps the on look. A disabled toggle takes the shared disabled look, and an on one keeps its rim.
Pressing it switches it. The wrapper holds its own state, or follows the state the page gives it and reports each press. Nothing animates.
Accessibility
What it does for you
- It is a real button that says whether it is pressed, so a screen reader reads "pressed" or "not pressed" after its name.
- Space and Enter press it. It is one stop in the tab order.
- On is never told by color alone: the fill, the shadow and the edge all change.
What you must do
- Keep its name the same on and off: "Bold", not "Make bold" and "Remove bold". The pressed state says which it is.
- Give an icon-only toggle an accessible name. Without one the wrapper warns in development and names it by its icon's words, which say what it shows, not what it turns on.
- In markup written by hand, give it the button's classes and the toggle's mark, set the pressed attribute to true or false, and switch it on each press.
How to test
- Tab to it: the focus ring shows, in both themes and in a forced-color mode. Press Space, then Enter: each switches it.
- With a screen reader, it is read as a button by its name, with "pressed" or "not pressed", and its name does not change when it is switched.
- Check that on and off differ by the fill, the shadow and the edge, not by color alone.
Source
The files the toggle button is made of. Its folder on GitHub (opens in a new tab) holds them with its wrapper and its document.
Stylesheet
/* smbk-toggle-button — Toggle button. Figma "Toggle button" 7125:4263: On × State × Size, 24 variants.
* The toggle button is the button with aria-pressed, and the button's stylesheet draws it: off is the outline or
* ghost button exactly, and on (the sunken fill, the rim and the strong inset shadow) is in button/button.css, under
* "on". Its markup carries the button's classes, its mark smbk-toggle-button and aria-pressed.
* This file holds no rules: the toggle button's own class is only its mark in markup. */Tokens it reads
| Token and CSS | Value | Preview | Foundation |
|---|---|---|---|
| space.inline.md--smbk-space-inline-md | comfortable: 8pxcompact: 6pxchanges with density | Spacing | |
| size.control.md--smbk-size-control-md | comfortable: 40pxcompact: 32pxchanges with density | Size | |
| space.inset.xl--smbk-space-inset-xl | comfortable: 16pxcompact: 12pxchanges with density | Spacing | |
| border-width.hairline--smbk-border-width-hairline | 1px | Border width | |
| radius.control.sm--smbk-radius-control-sm | 4px | Radius | |
| color.action.brand.background--smbk-color-action-brand-background | #cc0d0d | Color | |
| color.action.brand.border--smbk-color-action-brand-border | #ffffff1a | Color | |
| color.action.brand.foreground--smbk-color-action-brand-foreground | #f9fafb | Color | |
| typography.label-lg--smbk-typography-label-lg-font-family--smbk-typography-label-lg-font-size--smbk-typography-label-lg-font-weight--smbk-typography-label-lg-line-height--smbk-typography-label-lg-letter-spacing--smbk-typography-label-lg-text-transform | fontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 16pxfontWeight: 500lineHeight: 1.4letterSpacing: 0px | The quick brown fox | Typography |
| focus.ring.width--smbk-focus-ring-width | 2px | Focus | |
| color.border.focus--smbk-color-border-focus | light: #cc0d0ddark: #f34336changes with theme | Color | |
| focus.ring.offset--smbk-focus-ring-offset | 2px | Focus | |
| size.icon.md--smbk-size-icon-md | 20px | Size | |
| color.action.disabled.foreground--smbk-color-action-disabled-foreground | light: #7c8692dark: #606a75changes with theme | Color | |
| color.action.brand.background-hover--smbk-color-action-brand-background-hover | #a51d17 | Color | |
| color.action.brand.border-hover--smbk-color-action-brand-border-hover | #0000000d | Color | |
| elevation.inset--smbk-elevation-inset | light: inset 0px 0px 1px 0px #373d434ddark: inset 0px 0px 1px 0px #00000066 | Elevation | |
| color.action.brand.background-pressed--smbk-color-action-brand-background-pressed | #761812 | Color | |
| color.action.secondary.background--smbk-color-action-secondary-background | light: #373d4326dark: #606a7533changes with theme | Color | |
| color.action.secondary.foreground--smbk-color-action-secondary-foreground | light: #2d3237dark: #c4cdd8changes with theme | Color | |
| color.action.secondary.background-hover--smbk-color-action-secondary-background-hover | light: #373d4333dark: #606a754dchanges with theme | Color | |
| color.action.secondary.background-pressed--smbk-color-action-secondary-background-pressed | light: #373d4340dark: #606a7566changes with theme | Color | |
| color.action.outline.border--smbk-color-action-outline-border | light: #c4cdd8dark: #373d43changes with theme | Color | |
| color.action.outline.foreground--smbk-color-action-outline-foreground | light: #2d3237dark: #c4cdd8changes with theme | Color | |
| color.action.outline.background-hover--smbk-color-action-outline-background-hover | light: #373d431adark: #606a751achanges with theme | Color | |
| color.action.outline.border-hover--smbk-color-action-outline-border-hover | light: #9ba5b1dark: #4e555echanges with theme | Color | |
| color.action.outline.background-pressed--smbk-color-action-outline-background-pressed | light: #c4cdd8dark: #2d3237changes with theme | Color | |
| color.action.outline.border-pressed--smbk-color-action-outline-border-pressed | light: #7c8692dark: #606a75changes with theme | Color | |
| color.action.ghost.foreground--smbk-color-action-ghost-foreground | light: #2d3237dark: #c4cdd8changes with theme | Color | |
| color.action.ghost.background-hover--smbk-color-action-ghost-background-hover | light: #373d4326dark: #606a754dchanges with theme | Color | |
| color.action.ghost.background-pressed--smbk-color-action-ghost-background-pressed | light: #c4cdd8dark: #2d3237 | Color | |
| color.action.danger.background--smbk-color-action-danger-background | light: #febdb2dark: #4b130echanges with theme | Color | |
| color.action.danger.border--smbk-color-action-danger-border | #0000000d | Color | |
| color.action.danger.foreground--smbk-color-action-danger-foreground | light: #761812dark: #febdb2changes with theme | Color | |
| color.action.danger.background-hover--smbk-color-action-danger-background-hover | light: #fe7d6ddark: #761812changes with theme | Color | |
| color.action.danger.border-hover--smbk-color-action-danger-border-hover | light: #cc0d0d4ddark: #f34336changes with theme | Color | |
| color.action.danger.foreground-hover--smbk-color-action-danger-foreground-hover | light: #2a0403dark: #fee5e1changes with theme | Color | |
| color.action.danger.background-pressed--smbk-color-action-danger-background-pressed | light: #f34336dark: #a51d17changes with theme | Color | |
| color.action.disabled.background--smbk-color-action-disabled-background | light: #373d4314dark: #606a751achanges with theme | Color | |
| color.action.disabled.border--smbk-color-action-disabled-border | light: #c4cdd8dark: #2d3237changes with theme | Color | |
| color.surface.sunken--smbk-color-surface-sunken | light: #373d430ddark: #00000066changes with theme | Color | |
| color.border.rim--smbk-color-border-rim | light: #ffffffe6dark: #ffffff0dchanges with theme | Color | |
| elevation.inset-strong--smbk-elevation-inset-strong | light: inset -1px 2px 2px 0px #373d4333dark: inset -1px 2px 2px 0px #0000004d | Elevation | |
| size.control.lg--smbk-size-control-lg | comfortable: 48pxcompact: 40pxchanges with density | Size | |
| space.inset.2xl--smbk-space-inset-2xl | comfortable: 24pxcompact: 16pxchanges with density | Spacing | |
| radius.control.md--smbk-radius-control-md | 6px | Radius | |
| space.inline.sm--smbk-space-inline-sm | comfortable: 6pxcompact: 4pxchanges with density | Spacing | |
| size.control.sm--smbk-size-control-sm | comfortable: 32pxcompact: 28pxchanges with density | Size | |
| space.inset.lg--smbk-space-inset-lg | comfortable: 12pxcompact: 8pxchanges with density | Spacing | |
| typography.label-md--smbk-typography-label-md-font-family--smbk-typography-label-md-font-size--smbk-typography-label-md-font-weight--smbk-typography-label-md-line-height--smbk-typography-label-md-letter-spacing--smbk-typography-label-md-text-transform | fontFamily: Geist, Geist Fallback, system-ui, sans-seriffontSize: 14pxfontWeight: 500lineHeight: 1.4letterSpacing: 0px | The quick brown fox | Typography |
| size.icon.sm--smbk-size-icon-sm | 16px | Size | |
| space.inline.xs--smbk-space-inline-xs | 4px | Spacing | |
| size.control.xs--smbk-size-control-xs | 24px | Size | |
| space.inset.md--smbk-space-inset-md | comfortable: 8pxcompact: 6pxchanges with density | Spacing | |
| size.icon.xs--smbk-size-icon-xs | 12px | Size | |
| size.target.comfortable--smbk-size-target-comfortable | 44px | Size |
Manifest
{
"name": "toggle-button",
"block": "smbk-toggle-button",
"drawnBy": "smbk-btn",
"summary": "A button that stays on or off, such as bold text, a map layer or a filter: the outline or ghost button when off, sunken into the page when on.",
"adapt": "css",
"axes": {
"tone": {
"values": [
"outline",
"ghost"
],
"default": "outline",
"description": "How it looks when off: the outline button, or the ghost button with no fill or edge, for a tool among others in a toolbar. On looks the same in both. Figma draws the outline toggle; the ghost one is the toolbar’s tool."
},
"size": {
"values": [
"lg",
"md",
"sm"
],
"default": "md",
"description": "The button’s own heights, padding, label and icon, one recipe per height. md fits apps and forms."
}
},
"flags": {
"icon-only": {
"description": "A square toggle holding one icon and no label, for a toolbar. Needs an accessible name."
}
},
"parts": [
"icon",
"label"
],
"figmaNodeId": "7125:4263"
}