Tabs
Organize content into switchable panels. Use tabs when you have related content that users don't need to see simultaneously.
Basic Tabs
Standard Tabs
Simple tab navigation with underline indicator.
This is the overview content. It provides a high-level summary of the main topic.
Features content goes here. List the key capabilities and benefits.
Settings panel with configuration options and preferences.
<div class="tabs" role="tablist">
<button class="tab active" role="tab" aria-selected="true">Overview</button>
<button class="tab" role="tab" aria-selected="false">Features</button>
<button class="tab" role="tab" aria-selected="false">Settings</button>
</div>
<div class="tab-panels">
<div class="tab-panel active" role="tabpanel">Content...</div>
</div>
Tab Variants
Pill Tabs
Contained style with background highlight.
<div class="tabs tabs-pill" role="tablist">
<button class="tab active">Daily</button>
<button class="tab">Weekly</button>
<button class="tab">Monthly</button>
</div>
Boxed Tabs
Bordered container with elevated active state.
<div class="tabs tabs-boxed" role="tablist">
<button class="tab active">All</button>
<button class="tab">Active</button>
</div>
Tabs with Icons
Icon + Label
Icons provide visual context alongside text labels.
<button class="tab active">
<svg>...</svg>
Profile
</button>
Icon Only
Compact tabs using only icons (with aria-label for accessibility).
<div class="tabs tabs-icon-only">
<button class="tab active" aria-label="Grid view">
<svg>...</svg>
</button>
</div>
Tabs with Badge
Count Badges
Show item counts or notification indicators.
<button class="tab active">
Inbox
<span class="tab-badge">12</span>
</button>
<!-- Dot indicator -->
<button class="tab">
Spam
<span class="tab-badge tab-badge-dot"></span>
</button>
CSS Implementation
/* Base Tabs */
.tabs {
display: flex;
gap: var(--space-1);
border-bottom: 1px solid var(--border-subtle);
padding-bottom: 1px;
}
.tab {
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-3) var(--space-4);
font-family: var(--font-body);
font-size: var(--text-sm);
font-weight: var(--font-weight-medium);
color: var(--text-muted);
background: transparent;
border: none;
border-bottom: 2px solid transparent;
margin-bottom: -2px;
cursor: pointer;
transition: all var(--duration-fast) var(--ease-ease-out);
}
.tab:hover {
color: var(--text-primary);
}
.tab.active {
color: var(--accent-text);
border-bottom-color: var(--accent-primary);
}
/* Pill Variant */
.tabs-pill {
border-bottom: none;
background: var(--bg-secondary);
padding: var(--space-1);
border-radius: var(--radius-lg);
gap: var(--space-1);
}
.tabs-pill .tab {
border-bottom: none;
margin-bottom: 0;
border-radius: var(--radius-md);
padding: var(--space-2) var(--space-4);
}
.tabs-pill .tab.active {
background: var(--bg-elevated);
color: var(--text-primary);
box-shadow: var(--shadow-sm);
}
/* Boxed Variant */
.tabs-boxed {
border: 1px solid var(--border-subtle);
border-radius: var(--radius-lg);
padding: var(--space-1);
background: var(--bg-secondary);
}
.tabs-boxed .tab {
border-bottom: none;
margin-bottom: 0;
border-radius: var(--radius-md);
}
.tabs-boxed .tab.active {
background: var(--bg-elevated);
box-shadow: var(--shadow-sm);
}
/* Icon Only */
.tabs-icon-only .tab {
padding: var(--space-2);
}
/* Tab Badge */
.tab-badge {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 18px;
height: 18px;
padding: 0 var(--space-1);
font-size: var(--text-2xs);
font-weight: var(--font-weight-semibold);
background: var(--bg-tertiary);
border-radius: var(--radius-full);
}
.tab.active .tab-badge {
background: var(--accent-subtle);
color: var(--accent-text);
}
.tab-badge-dot {
width: 8px;
height: 8px;
min-width: 8px;
padding: 0;
background: var(--error);
}
/* Tab Panels */
.tab-panels {
padding: var(--space-6) 0;
}
.tab-panel {
display: none;
}
.tab-panel.active {
display: block;
animation: tab-fade-in var(--duration-normal) var(--ease-ease-out);
}
@keyframes tab-fade-in {
from { opacity: 0; transform: translateY(4px); }
to { opacity: 1; transform: translateY(0); }
}
Accessibility
Keyboard Navigation
Arrow keys move between tabs. Home/End jump to first/last tab. Enter/Space activates.
ARIA Roles
Use role="tablist" on container, role="tab" on buttons, role="tabpanel" on content.
Selection State
aria-selected="true" on active tab, aria-selected="false" on others.
Icon-Only Labels
Always include aria-label on icon-only tabs to describe their purpose.