Tabs
Switches between a few views on the same page.
Examples
24 transactions this month.
$1,284.60
in May
States
rest
hover
focus-visible
disabled
Usage
When to use it
- Use
- Two to five views of the same collection: Activity, Scheduled, Shared.
- Use
- Panels of one screen where one is wanted at a time.
- Not for
- Setting a value, such as a layout or a unit. Use Segmented.
- Not for
- A long list of sections that open in place. Use Accordion.
- Not for
- Moving to another page with its own address. Use links.
Rules
7 rules
- Must
- Make tabs parallel views of one thing, not unrelated sections. Because people expect every tab to show the same data another way, so Help there goes unfound.
- Never
- Use Tabs to set a value such as grid or list; use Segmented. Because Tabs announce a tab and a panel, so a view setting is read as a section change.
- Must
- Name a tab in one or two words in sentence case. Because labels never wrap, so a long one truncates at 192px and loses its last words.
- Never
- Restyle tabs as filled pills; the underline tells them from Segmented and Chip. Because a lime pill reads as the primary action or a filter chip, not a view.
- Must
- Keep five tabs or fewer. Because the row neither wraps nor scrolls, so a sixth tab squeezes every label to an ellipsis.
- Must
- Leave TabsContent focusable so a keyboard user can reach and scroll a text panel. Because a panel of plain text has no other tab stop, so arrow keys cannot scroll it.
- Should
- Show loading and errors inside the panel; the tab switches at once.
Accessibility
4 checks
- TabsList is role tablist, each tab role tab with aria-selected, and each panel role tabpanel.
- Tab enters the list on the selected tab; arrows move; Tab then goes to the panel.
- Arrow keys follow the reading direction in RTL.
- The underline is a background fill, so forced colors may drop it; check in emulation.
Edge cases
6 edge cases
- Long label
- The label truncates; the row stays inside its container and does not scroll.
- Narrow container
- The triggers share the width and their labels truncate.
- Right to left
- The row reverses and the underline positions from the start edge.
- Reduced motion
- The underline jumps with no slide.
- Empty panel
- The tab still switches; an unlabeled tab is an unnamed button.
- Tabs inside tabs
- Valid but confusing; avoid.
API
5 props
TabsBase UI Tabs.Root propsTabsListBase UI Tabs.List propsTabsTrigger valuestringdefaultrequiredTabsTrigger disabledbooleandefaultfalseTabsContent valuestringdefaultrequired
Tokens
11 tokens
--line- #e6e4df
--fg-3- #6b6a63
--fg- #0f0f0d
--fg-disabled- #a6a49b
--ink- #0f0f0d
--text-sm- 14px
--weight-medium- 500
--control-md- 40px
--dur-base- 200ms
--dur-instant- 80ms
--ease-out- cubic-bezier(0.16, 1, 0.3, 1)