Skip to main content

Tabs

Switches between views of the same thing on one page.

In Accessible first

See it live​

Start Storybook to see it live: npm run storybook

When to use it​

In Accessible first: Related views of one application, such as answers and documents. Not the steps of a form.

  • Use it when: Related views of one object that people move between.
  • Not when: Navigation to other pages (links), or steps of a task (progress).

Instead:

Words​

  • Use common words. Explain any term you must use.
  • One idea per sentence. Put the action first.
  • Never blame the person.
  • Use: Continue, Change, Start, You. Avoid: Invalid, Utilise, Submit, Error code.

The labels components use, from the voice tokens:

  • content.action.commit: Continue
  • content.action.cancel: Go back
  • content.action.destroy: Delete
  • content.action.retry: Try again
  • content.action.empty-action: Start a new application

See Voice and tone for the whole voice.

Accessibility and keyboard​

KeyboardWhat happensNot
undefinedArrow keys move between tabs; Tab moves into the panel.undefined

Test before you ship:

  • It is a tablist; the selected tab owns its panel. undefined

Use it in code​

npx open-ds add tabs

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

Tokens it reads​

Tabs reads 14 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 Tabs's tokens to change Tabs alone.

Changes with theme

Accessible 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
Shared
Button focus ring
Changes with theme
on focus
component.button.focus-ringcolor.border.focusvar(--button-focus-ring)Lightblue.light.600:#0B4FC0Darkblue.dark.600:#8AB4F8
Tabs
Indicator
Changes with theme
component.tabs.indicatorcolor.action.primaryvar(--tabs-indicator)Lightblue.light.600:#0B4FC0Darkblue.dark.600:#8AB4F8
Focus
on focus
component.tabs.focusborder-width.focusvar(--tabs-focus)border-width.3:3px
Canvas
Changes with theme
on focus
component.tabs.canvascolor.surface.canvasvar(--tabs-canvas)Lightgray.light.50:#F7F7F7Darkgray.dark.0:#0A0A0A
Text
Color
Changes with theme
component.tabs.labelcolor.text.secondaryvar(--tabs-label)Lightgray.light.700:#333333Darkgray.dark.600:#B4B4B4
Active
Changes with theme
component.tabs.label.activecolor.text.primaryvar(--tabs-label-active)Lightgray.light.900:#141414Darkgray.dark.900:#F7F7F7
List
Gapcomponent.tabs.list.gapspace.gap.groupvar(--tabs-list-gap)space.32:2rem
Border widthcomponent.tabs.list.border-widthborder-width.defaultvar(--tabs-list-border-width)border-width.2:2px
Border
Changes with theme
component.tabs.list.bordercolor.border.defaultvar(--tabs-list-border)Lightgray.light.200:#D6D6D6Darkgray.dark.100:#222222
Trigger
Heightcomponent.tabs.trigger.heightsize.control.defaultvar(--tabs-trigger-height)size.52:3.25rem
Font familycomponent.tabs.trigger.font-familytype.label.font-familyvar(--tabs-trigger-font-family)font.family.atkinson-hyperlegible:"Atkinson Hyperlegible", Verdana, sans-serif
Text sizecomponent.tabs.trigger.font-sizetype.label.font-sizevar(--tabs-trigger-font-size)font.size.18:1.125rem
Weightcomponent.tabs.trigger.font-weighttype.label.font-weightvar(--tabs-trigger-font-weight)font.weight.700:700
Content
Padding, topcomponent.tabs.content.padding-topspace.gap.defaultvar(--tabs-content-padding-top)space.16:1rem