Rost
← All components
component

Tabs

A row of tabs on a 1px line. One is selected, and its panel shows below.

In codeContract: reviewGuidance: agreedContract on GitHubFigma 448:56
tabs

When to use

  • Above the panels it switches between.

When not to use

  • More tabs than fit on one line. Fewer, or a menu.

Behaviour

One tab is selected at a time. Changing it swaps the panel below; nothing else on the page moves.

Accessibility

  • Element: role="tablist" holding the tabs. Each panel is a role="tabpanel" labelled by its tab.
  • Name: an aria-label on the tablist that says what it switches, like "Example".
  • Keyboard: Tab lands on the selected tab and the next Tab goes into its panel. Arrow keys, Home and End move between tabs (see TabItem).
  • Focus: on the tabs themselves, each with its own focus-ring.

Content

Tabs that belong together, in the order people need them.

Props

PropTypeValuesDefault
tabsslot

Values

Straight from the contract. Each value sits next to its token, because six tokens here all come out as #3a3a3a and the colour alone can't tell you which one is right.

Never changes

PartPropertyValueToken
rootdisplayflexlayout
rootalign-itemsflex-startlayout
rootgap0pxFigma frame size
rootbox-shadowinset 0 calc(-1 * var(--spacing-outline-small)) 0 0 var(--tabs-line)on purpose: Figma's 1px line along the bottom, drawn inside so the row stays 40px tall and the selected tab's underline sits on top of it. The width and colour are tokens (spacing/outline/small, tabs/line).
Part of Tabs

TabItem

One tab in a row of tabs. A label, optional icons before and after it, and a green underline when it's the one selected.

In codeContract: reviewGuidance: agreedContract on GitHubFigma 442:94
selected · Default
selected · Disabled
not selected · Default
not selected · Disabled

Hover, press or tab to one to see the other 6 states.

When to use

  • Switching between views of the same thing, in place: Preview and Code, Overview and Activity.

When not to use

  • Going to another page. That's a link, or the nav.
  • Turning one thing on and off. That's Toggle.

Behaviour

Always inside Tabs, and exactly one is selected. Selecting a tab shows its panel straight away. Hover, pressed and focus come from the browser; selected and disabled are props.

Accessibility

  • Element: <button role="tab"> with aria-selected and aria-controls, inside a role="tablist" that has a name.
  • Name: the label.
  • Keyboard: Only the selected tab is in the tab order. Arrow keys move between tabs, Home and End go to the first and last.
  • Focus: the focus-ring part, on :focus-visible.
  • Icons: just decoration, aria-hidden. The label is the name.

Content

One or two words, sentence case. The same kind of thing in every tab.

Props

PropTypeValuesDefault
labelslot
selectedbooleanfalse
leadingslot
trailingslot

States: Default, Hover, Pressed, Focus, Disabled.

Values

Straight from the contract. Each value sits next to its token, because six tokens here all come out as #3a3a3a and the colour alone can't tell you which one is right.

Never changes

PartPropertyValueToken
rootdisplayinline-flexlayout
rootalign-itemscenterlayout
rootjustify-contentcenterlayout
rootpositionrelativelayout
rootbackgroundnoneFigma frame size
rootbordernoneFigma frame size
rootfontinheritFigma frame size
rootcursorpointerFigma frame size
rootoutlinenoneFigma frame size
rootgap8pxspacing/gap/small
rootheight40pxspacing/size/medium
rootpadding-left16pxspacing/gap/medium
rootpadding-right16pxspacing/gap/medium
rootpadding-top0pxFigma frame size
rootpadding-bottom0pxFigma frame size
leadingdisplayflexlayout
leadingflex-shrink0layout
leadingwidth20pxspacing/size/xsmall
leadingheight20pxspacing/size/xsmall
labelwhite-spacenowraplayout
labelfont-family'General Sans Variable'font-family/base
labelfont-weight500typography/body/font-weight/medium
labelline-height22pxtypography/body/line-height
labelfont-size16pxtypography/body/font-size
labelletter-spacing0pxtypography/body/letter-spacing
trailingdisplayflexlayout
trailingflex-shrink0layout
trailingwidth20pxspacing/size/xsmall
trailingheight20pxspacing/size/xsmall
underlinepositionabsolutelayout
underlineleft0Figma frame size
underlineright0Figma frame size
underlinebottom0Figma frame size
underlineheight2pxspacing/outline/medium
underlinepointer-eventsnoneFigma frame size
focus-ringdisplaynonelayout
focus-ringpositionabsolutelayout
focus-ringinset0layout
focus-ringborder-stylesolidno token yet
focus-ringborder-width2pxspacing/outline/medium
focus-ringborder-radius8pxspacing/radius/small
focus-ringpointer-eventsnoneFigma frame size

Changes by variant

focus-ring.border-color2
state=Focus, selected=True#b6ffdatabs/selected/focus/focus-ring
state=Focus, selected=False#999999tabs/unselected/focus/focus-ring
focus-ring.display2
state=Focus, selected=Trueblocklayout
state=Focus, selected=Falseblocklayout
root.color10
state=Default, selected=True#edededtabs/selected/default/label
state=Hover, selected=True#edededtabs/selected/hover/label
state=Pressed, selected=True#edededtabs/selected/pressed/label
state=Focus, selected=True#edededtabs/selected/focus/label
state=Disabled, selected=True#d3d9d5tabs/selected/disabled/label
state=Default, selected=False#999999tabs/unselected/default/label
state=Hover, selected=False#edededtabs/unselected/hover/label
state=Pressed, selected=False#d3d9d5tabs/unselected/pressed/label
state=Focus, selected=False#d3d9d5tabs/unselected/focus/label
state=Disabled, selected=False#999999tabs/unselected/disabled/label
root.opacity2
state=Disabled, selected=True0.48opacity/medium
state=Disabled, selected=False0.48opacity/medium
underline.background7
state=Default, selected=True#00d669tabs/selected/default/underline
state=Hover, selected=True#00b450tabs/selected/hover/underline
state=Pressed, selected=True#00913atabs/selected/pressed/underline
state=Focus, selected=True#00d669tabs/selected/focus/underline
state=Disabled, selected=True#00d669tabs/selected/disabled/underline
state=Hover, selected=False#3a3a3atabs/unselected/hover/underline
state=Pressed, selected=False#747573tabs/unselected/pressed/underline