Skip to main content

Toggle

A button that stays pressed or not.

Left out of Content first Readers need sections, navigation and little else. Toggles format text in a toolbar, and Content first avoids screens with many actions. Use instead: Button

See it live​

Start Storybook to see it live: npm run storybook

When to use it​

  • Use it when: Turning a mode or format on and off in a toolbar, such as bold.
  • Not when: A setting saved at once (switch), or a one-off action (button).

Instead:

Variants​

What each variant is for in any design system, then what Content first decided and why. Each sample is the live story with that variant set.

defaultvariantNot decided yet
Start Storybook to see it live

What it is for

No border; the pressed state shows as a fill.

✓Toolbars where toggles sit together.
✕A toggle alone on a busy background.

In Content first

Not decided yet.

outlinevariantNot decided yet
Start Storybook to see it live

What it is for

A border, so the toggle reads as a control at rest.

✓A toggle that stands alone.
✕A dense toolbar of many toggles.

In Content first

Not decided yet.

defaultsizeNot decided yet
Start Storybook to see it live

What it is for

The normal size.

✓Most toolbars.
✕Very dense toolbars.

In Content first

Not decided yet.

smsizeNot decided yet
Start Storybook to see it live

What it is for

A smaller toggle.

✓Dense toolbars and compact panels.
✕Touch screens.

In Content first

Not decided yet.

lgsizeNot decided yet
Start Storybook to see it live

What it is for

A larger toggle.

✓A few toggles that need to be easy to hit.
✕Dense toolbars.

In Content first

Not decided yet.

Words​

  • Write to one person: "you", not "users".
  • Short sentences with room to breathe.
  • Explain why before asking for anything.
  • Use: Read, Save for later, You, Next issue. Avoid: Click here, Submit, Users, Content.

The labels components use, from the voice tokens:

  • content.action.commit: Save
  • content.action.cancel: Not now
  • content.action.destroy: Remove
  • content.action.retry: Try again
  • content.action.empty-action: Browse guides

See Voice and tone for the whole voice.

Accessibility and keyboard​

KeyboardWhat happensNot
undefinedSpace or Enter presses it.undefined

Test before you ship:

  • It says whether it is pressed. undefined

Use it in code​

npx open-ds add toggle

The component reads only component keys and semantic tokens, so it follows the brand and mode on <html>.

Tokens it reads​

Toggle reads 24 tokens of its own, each an alias of a semantic token. Each row is one part: its own token, the semantic it aliases, and the value it ends at. Change a semantic and every component that reads it follows; override one of Toggle's tokens to change Toggle alone.

Changes with theme

Content first decides what changes when you switch theme. Here a switch changes colors only, so the marked rows differ between light and dark; everything else holds steady.

PartIts token and the semantic it aliasesValue
Toggle
Gapcomponent.toggle.gapspace.gap.defaultvar(--toggle-gap)space.16:1rem
Cornercomponent.toggle.radiusradius.controlvar(--toggle-radius)radius.8:0.5rem
Text sizecomponent.toggle.font-sizetype.body.font-sizevar(--toggle-font-size)font.size.18:1.125rem
Weightcomponent.toggle.font-weighttype.label.font-weightvar(--toggle-font-weight)font.weight.600:600
Background hover
Changes with theme
on hover
component.toggle.background-hovercolor.surface.sunkenvar(--toggle-background-hover)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Label hover
Changes with theme
on hover
component.toggle.label-hovercolor.text.mutedvar(--toggle-label-hover)Lightstone.light.600:#61594DDarkstone.dark.400:#A39A8B
Border focus
Changes with theme
on focus
component.toggle.border-focuscolor.border.focusvar(--toggle-border-focus)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Disabled opacity disabled
when disabled
component.toggle.disabled-opacity-disabledopacity.disabledvar(--toggle-disabled-opacity-disabled)opacity.40:0.4
Border invalid
Changes with theme
when invalid
component.toggle.border-invalidcolor.status.dangervar(--toggle-border-invalid)Lightred.light.600:#C42B2BDarkred.dark.600:#F28B8B
Focus ring invalid
Changes with theme
when invalid
component.toggle.focus-ring-invalidcolor.status.dangervar(--toggle-focus-ring-invalid)Lightred.light.600:#C42B2BDarkred.dark.600:#F28B8B
Background on
Changes with theme
when on
component.toggle.background-oncolor.surface.sunkenvar(--toggle-background-on)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Label on
Changes with theme
when on
component.toggle.label-oncolor.text.primaryvar(--toggle-label-on)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Icon sizecomponent.toggle.icon-sizesize.iconvar(--toggle-icon-size)size.16:1rem
Focus
on focus
component.toggle.focusborder-width.focusvar(--toggle-focus)border-width.2:2px
Focus ring focus
Changes with theme
on focus
component.toggle.focus-ring-focuscolor.border.focusvar(--toggle-focus-ring-focus)Lightnavy.light.600:#1E3A5FDarknavy.dark.600:#8FA6C4
Focus ring offset focus
Changes with theme
on focus
component.toggle.focus-ring-offset-focuscolor.surface.canvasvar(--toggle-focus-ring-offset-focus)Lightstone.light.50:#FFFDF8Darkstone.dark.0:#14110D
Outline
Border
Changes with theme
component.toggle.outline.bordercolor.border.strongvar(--toggle-outline-border)Lightstone.light.500:#7A7062Darkstone.dark.400:#A39A8B
Shadowcomponent.toggle.outline.shadowelevation.cardvar(--toggle-outline-shadow)shadow.none
Background hover
Changes with theme
on hover
component.toggle.outline.background-hovercolor.surface.sunkenvar(--toggle-outline-background-hover)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Label hover
Changes with theme
on hover
component.toggle.outline.label-hovercolor.text.primaryvar(--toggle-outline-label-hover)Lightstone.light.900:#1F1B16Darkstone.dark.900:#FFFDF8
Default
Padding, left and rightcomponent.toggle.default.padding-xcomponent-spacing-map.x2var(--toggle-default-padding-x)space.8:0.5rem
Sm
Heightcomponent.toggle.sm.heightsize.control.defaultvar(--toggle-sm-height)size.48:3rem
Padding, left and rightcomponent.toggle.sm.padding-xcomponent-spacing-map.x2var(--toggle-sm-padding-x)space.8:0.5rem
Lg
Padding, left and rightcomponent.toggle.lg.padding-xcomponent-spacing-map.x3var(--toggle-lg-padding-x)space.20:1.25rem