Segmented Control
Horizontal toggle between mutually exclusive options.
Selectors
.segmented-control- Wrapper for the pill-shaped segmented control.
[data-tab-list]- Container for segment buttons.
[data-tab]- Individual segment button.
[data-tab-indicator]- Sliding pill indicator positioned by JS.
[data-tab-panel]- Content panel toggled by the active segment.
Default
Total Users
2,847
Active Today
1,203
Uptime
99.98%
Page Views
48,291
Bounce Rate
32.4%
Avg. Session
4m 12s
Generated
12 reports
Last Export
Mar 15, 2025
<div class="segmented-control" data-tabs>
<div data-tab-list>
<div data-tab-indicator></div>
<button data-tab="seg-1" data-active>Overview</button>
<button data-tab="seg-2">Analytics</button>
<button data-tab="seg-3">Reports</button>
</div>
<div data-tab-panel="seg-1" data-active>
<div class="space-y-3">
<div class="flex items-center justify-between">
<span class="text-sm text-tertiary-foreground">Total Users</span>
<span class="text-sm font-semibold">2,847</span>
</div>
<div class="flex items-center justify-between">
<span class="text-sm text-tertiary-foreground">Active Today</span>
<span class="text-sm font-semibold">1,203</span>
</div>
<div class="flex items-center justify-between">
<span class="text-sm text-tertiary-foreground">Uptime</span>
<span class="text-sm font-semibold">99.98%</span>
</div>
</div>
</div>
<div data-tab-panel="seg-2">
<div class="space-y-3">
<div class="flex items-center justify-between">
<span class="text-sm text-tertiary-foreground">Page Views</span>
<span class="text-sm font-semibold">48,291</span>
</div>
<div class="flex items-center justify-between">
<span class="text-sm text-tertiary-foreground">Bounce Rate</span>
<span class="text-sm font-semibold">32.4%</span>
</div>
<div class="flex items-center justify-between">
<span class="text-sm text-tertiary-foreground">Avg. Session</span>
<span class="text-sm font-semibold">4m 12s</span>
</div>
</div>
</div>
<div data-tab-panel="seg-3">
<div class="space-y-3">
<div class="flex items-center justify-between">
<span class="text-sm text-tertiary-foreground">Generated</span>
<span class="text-sm font-semibold">12 reports</span>
</div>
<div class="flex items-center justify-between">
<span class="text-sm text-tertiary-foreground">Last Export</span>
<span class="text-sm font-semibold">Mar 15, 2025</span>
</div>
</div>
</div>
</div>
With Icons
<button class="btn-filled">Click me</button>
<div class="segmented-control" data-tabs>
<div data-tab-list>
<div data-tab-indicator></div>
<button data-tab="icon-1" data-active>
<svg class="size-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" aria-hidden="true"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
Preview
</button>
<button data-tab="icon-2">
<svg class="size-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" aria-hidden="true"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>
Code
</button>
</div>
<div data-tab-panel="icon-1" data-active>
<div class="rounded-xl border p-6 text-center">
<button class="btn-filled">Click me</button>
</div>
</div>
<div data-tab-panel="icon-2">
<div class="rounded-xl border bg-secondary/30 p-4">
<code class="text-sm text-tertiary-foreground"><button class="btn-filled">Click me</button></code>
</div>
</div>
</div>
Two Segments
alice@icloud.com
alice@acme.com
<div class="segmented-control" data-tabs>
<div data-tab-list>
<div data-tab-indicator></div>
<button data-tab="two-1" data-active>Personal</button>
<button data-tab="two-2">Business</button>
</div>
<div data-tab-panel="two-1" data-active>
<p class="text-sm text-tertiary-foreground">alice@icloud.com</p>
</div>
<div data-tab-panel="two-2">
<p class="text-sm text-tertiary-foreground">alice@acme.com</p>
</div>
</div>
Usage
Apple HIG segmented control. Uses the [data-tabs] JS (cider.js) for panel switching and indicator animation.
Accessibility
- Segments receive
role="tab"and panels receiverole="tabpanel"viacider.js. - Keyboard: Arrow Left / Right to move between segments, Home / End to jump to first or last.
- Uses roving
tabindex— only the active segment is in the tab order.