Navigation/Tabs

Tabs

A set of layered sections of content displayed one at a time.

Themed

When to Use

Use Tabs when you need to:

  • Organize related content into switchable sections within the same view
  • Reduce visual clutter by showing only one content panel at a time
  • Let users compare or switch between related data sets (e.g., Account vs. Password)
  • Create settings pages with logically grouped options
  • Display alternative views of the same content (e.g., Code vs. Preview)

When Not to Use

Default

Tabs with form content inside cards. The default variant uses a muted background container with rounded triggers.

Account
Make changes to your account here. Click save when you're done.

Simple

Basic tabs with simple text content. Ideal for lightweight content switching.

Make changes to your account here.

With Icons

Tabs with leading icons in the triggers. Icons help users identify tabs at a glance.

Preview content

Disabled

Tabs with disabled triggers. Disabled tabs cannot be activated and are visually dimmed.

This tab is active and can be selected.

Full Width

Tabs that expand to fill the available width. Each trigger grows equally using flex-1.

Overview
A high-level summary of your data.

This is the overview content. View your key metrics and recent activity here.

Folder Variant

Tabs styled like browser or file folder tabs. The active tab uses the primary color for strong emphasis.

Documents

23 files, 4.2 MB

Underline Variant

Clean tabs without a container background, using only an underline indicator for the active tab.

Profile Settings

Manage your public profile information and how others see you.

Variants Comparison

Side-by-side comparison of all three tab variants: default, folder, and underline.

Default

Folder

Underline

UX & Design Guidelines

Visual Hierarchy

Use the default variant for standard content switching within cards or panels. Choose variant="folder" when you need strong visual emphasis with bg-primary on the active tab. Use variant="underline" for lightweight, minimal tab bars that blend into content-heavy layouts.

Spacing & Layout

Tabs include a default gap-2 between the tab list and content. For full-width layouts, apply className="w-full" to both Tabs and TabsList, with flex-1 on each trigger. Keep the number of tabs between 3 and 7 for optimal scannability.

Responsive Behavior

On mobile, consider using full-width tabs so triggers span the viewport. For many tabs, wrap the tab list in a horizontal ScrollArea to prevent overflow. Icons help reduce label length on smaller screens. The underline variant works especially well on mobile due to its minimal chrome.

Color & Contrast

The default variant uses bg-muted for the list container and bg-background for the active trigger, providing subtle contrast. The folder variant leverages bg-primary with text-primary-foreground for high-contrast active states. Disabled triggers reduce opacity to 50% while maintaining readability.

Accessibility

Keyboard Navigation

  • Tab -- Move focus into the tab list, then to the active tab panel content
  • ArrowLeft / ArrowRight -- Navigate between tab triggers (horizontal orientation)
  • ArrowUp / ArrowDown -- Navigate between tab triggers (vertical orientation)
  • Home -- Move focus to the first tab trigger
  • End -- Move focus to the last tab trigger
  • Enter or Space -- Activate the focused tab (when activationMode="manual")

Screen Reader Support

  • Built on Radix UI Tabs, which provides correct role="tablist", role="tab", and role="tabpanel" semantics
  • Each trigger is automatically linked to its content via aria-controls and aria-labelledby
  • Active tab is announced via aria-selected="true"
  • Disabled state is communicated via disabled attribute on the trigger

Focus Management

Visible focus ring with focus-visible:ring-2 and ring-ring. In automatic activation mode, focus movement immediately activates the tab. In manual mode, focus and activation are separate, letting users review options before committing. Focus wraps cyclically through triggers.

Activation Modes

activationMode="automatic" (default) activates a tab as soon as it receives focus, following WAI-ARIA recommended behavior for fast switching. activationMode="manual" requires an explicit Enter or Space to activate, which is preferable when tab content is expensive to render.

ARIA Attributes

{/* Standard tabs with accessible labels */}
<Tabs defaultValue="account" aria-label="Account settings">
  <TabsList>
    <TabsTrigger value="account">Account</TabsTrigger>
    <TabsTrigger value="password">Password</TabsTrigger>
  </TabsList>
  <TabsContent value="account">...</TabsContent>
  <TabsContent value="password">...</TabsContent>
</Tabs>

{/* Controlled tabs with onValueChange */}
<Tabs
  value={activeTab}
  onValueChange={setActiveTab}
  aria-label="Dashboard navigation"
>
  <TabsList>
    <TabsTrigger value="overview">Overview</TabsTrigger>
    <TabsTrigger value="analytics">Analytics</TabsTrigger>
  </TabsList>
  <TabsContent value="overview">...</TabsContent>
  <TabsContent value="analytics">...</TabsContent>
</Tabs>

{/* Manual activation mode */}
<Tabs defaultValue="tab1" activationMode="manual">
  <TabsList>
    <TabsTrigger value="tab1">Tab 1</TabsTrigger>
    <TabsTrigger value="tab2">Tab 2</TabsTrigger>
  </TabsList>
  <TabsContent value="tab1">...</TabsContent>
  <TabsContent value="tab2">...</TabsContent>
</Tabs>

API Reference

The Tabs component is composed of four parts. Each accepts its own props in addition to standard HTML attributes.

Tabs

Root container that manages tab state and context.

PropTypeDefaultDescription
defaultValuestring---The value of the tab that should be active when initially rendered.
valuestring---Controlled value of the active tab.
onValueChange(value: string) => void---Event handler called when the active tab changes.
orientation"horizontal" | "vertical""horizontal"The orientation of the tabs.
activationMode"automatic" | "manual""automatic"When "automatic", tabs activate on focus. When "manual", tabs activate on click/Enter.

TabsList

Container for tab triggers. Controls the visual variant for all child triggers.

PropTypeDefaultDescription
variant"default" | "folder" | "underline""default"The visual style variant of the tab list. Determines container and trigger styling.
classNamestring---Additional CSS classes to apply to the tab list container.

TabsTrigger

Button that activates its associated content panel.

PropTypeDefaultDescription
valuestring---Unique value that associates the trigger with its content panel.
disabledbooleanfalseWhen true, prevents the tab from being activated and applies disabled styling.
classNamestring---Additional CSS classes to apply to the tab trigger.

TabsContent

Content panel displayed when its associated trigger is active.

PropTypeDefaultDescription
valuestring---Unique value that associates the content panel with its trigger.
forceMountboolean---Force mount the content panel even when inactive. Useful with animation libraries.
classNamestring---Additional CSS classes to apply to the content panel.