Library · Foundations
Tabs
A fully accessible tabs component following WAI-ARIA guidelines, with arrow-key navigation between tabs. Ships with four CSS skins — default (boxed), tabs-compact, tabs-underline, tabs-pill — applied via the class prop; skins live in primitives.css, not the vendored component.
Figma: Primitives / Tabs ↗---
import Tabs from "../components/primitives/tabs/Tabs.astro";
import TabsList from "../components/primitives/tabs/TabsList.astro";
import TabsTab from "../components/primitives/tabs/TabsTab.astro";
import TabsPanel from "../components/primitives/tabs/TabsPanel.astro";
---
<Tabs>
<TabsList>
<TabsTab id="tab-1" controls="panel-1" selected>Overview</TabsTab>
<TabsTab id="tab-2" controls="panel-2">Details</TabsTab>
<TabsTab id="tab-3" controls="panel-3">Support</TabsTab>
</TabsList>
<TabsPanel id="panel-1" labelledby="tab-1" selected>
<p>A short overview of the product goes here.</p>
</TabsPanel>
<TabsPanel id="panel-2" labelledby="tab-2">
<p>Detailed specifications and information live in this panel.</p>
</TabsPanel>
<TabsPanel id="panel-3" labelledby="tab-3">
<p>Support resources and contact options appear here.</p>
</TabsPanel>
</Tabs> ---
import Tabs from "../components/primitives/tabs/Tabs.astro";
import TabsList from "../components/primitives/tabs/TabsList.astro";
import TabsTab from "../components/primitives/tabs/TabsTab.astro";
import TabsPanel from "../components/primitives/tabs/TabsPanel.astro";
---
<Tabs class="tabs-compact">
<TabsList>
<TabsTab id="ctab-1" controls="cpanel-1" selected>Overview</TabsTab>
<TabsTab id="ctab-2" controls="cpanel-2">Details</TabsTab>
<TabsTab id="ctab-3" controls="cpanel-3">Support</TabsTab>
</TabsList>
<TabsPanel id="cpanel-1" labelledby="ctab-1" selected>
<p>Same boxed style, compact density.</p>
</TabsPanel>
<TabsPanel id="cpanel-2" labelledby="ctab-2">
<p>Detailed specifications and information live in this panel.</p>
</TabsPanel>
<TabsPanel id="cpanel-3" labelledby="ctab-3">
<p>Support resources and contact options appear here.</p>
</TabsPanel>
</Tabs> ---
import Tabs from "../components/primitives/tabs/Tabs.astro";
import TabsList from "../components/primitives/tabs/TabsList.astro";
import TabsTab from "../components/primitives/tabs/TabsTab.astro";
import TabsPanel from "../components/primitives/tabs/TabsPanel.astro";
---
<Tabs class="tabs-pill">
<TabsList>
<TabsTab id="ptab-1" controls="ppanel-1" selected>Overview</TabsTab>
<TabsTab id="ptab-2" controls="ppanel-2">Details</TabsTab>
<TabsTab id="ptab-3" controls="ppanel-3">Support</TabsTab>
</TabsList>
<TabsPanel id="ppanel-1" labelledby="ptab-1" selected>
<p>Pill tabs work well for view switchers and filters.</p>
</TabsPanel>
<TabsPanel id="ppanel-2" labelledby="ptab-2">
<p>Detailed specifications and information live in this panel.</p>
</TabsPanel>
<TabsPanel id="ppanel-3" labelledby="ptab-3">
<p>Support resources and contact options appear here.</p>
</TabsPanel>
</Tabs> ---
import Tabs from "../components/primitives/tabs/Tabs.astro";
import TabsList from "../components/primitives/tabs/TabsList.astro";
import TabsTab from "../components/primitives/tabs/TabsTab.astro";
import TabsPanel from "../components/primitives/tabs/TabsPanel.astro";
---
<Tabs class="tabs-underline">
<TabsList>
<TabsTab id="utab-1" controls="upanel-1" selected>Overview</TabsTab>
<TabsTab id="utab-2" controls="upanel-2">Details</TabsTab>
<TabsTab id="utab-3" controls="upanel-3">Support</TabsTab>
</TabsList>
<TabsPanel id="upanel-1" labelledby="utab-1" selected>
<p>Underline tabs suit content-heavy pages and settings screens.</p>
</TabsPanel>
<TabsPanel id="upanel-2" labelledby="utab-2">
<p>Detailed specifications and information live in this panel.</p>
</TabsPanel>
<TabsPanel id="upanel-3" labelledby="utab-3">
<p>Support resources and contact options appear here.</p>
</TabsPanel>
</Tabs> Props
| Name | Type | Required | Description |
|---|---|---|---|
class | string | — | Additional classes to apply to the tabs container |
[key: string] | unknown | — | HTML attributes to spread on the tabs container |
List: class | string | — | Additional classes to apply to the tabs list container |
List: [key: string] | unknown | — | HTML attributes to spread on the tabs list |
Tab: class | string | — | Additional classes to apply to the tab |
Tab: id | string | Yes | Unique identifier for the tab |
Tab: controls | string | Yes | ID of the panel this tab controls |
Tab: selected | boolean | — | Whether this tab is currently selected (default: false) |
Tab: [key: string] | string | number | boolean | undefined | — | HTML attributes to spread on the tab |
Panel: class | string | — | Additional classes to apply to the panel |
Panel: id | string | Yes | Unique identifier for the panel |
Panel: labelledby | string | Yes | ID of the tab that labels this panel |
Panel: selected | boolean | — | Whether this panel is currently selected (default: false) |
Panel: [key: string] | string | number | boolean | undefined | — | HTML attributes to spread on the panel |
Example with all props
<Tabs class="tabs-underline" data-section="docs">
<TabsList class="product-tabs" aria-label="Product information">
<TabsTab class="product-tab" id="tab-a" controls="panel-a" selected>Overview</TabsTab>
<TabsTab id="tab-b" controls="panel-b">Details</TabsTab>
</TabsList>
<TabsPanel class="product-panel" id="panel-a" labelledby="tab-a" selected>
<p>First panel content.</p>
</TabsPanel>
<TabsPanel id="panel-b" labelledby="tab-b">
<p>Second panel content.</p>
</TabsPanel>
</Tabs>