Tabs
Material Design 3 tabs for organizing content into separate views. Tabs enable navigation between groups of related content within a single context. Not intended for multi-page routing between distinct URL destinations; use anchor navigation or a router for that.
Basic Usage
Simple tabs that organize content into separate views. Tab content panels are slotted, so any markup can appear in a panel without page navigation:
Flights
Search for flights to your destination. Compare prices across airlines and find the best deals for your travel dates.
Hotels
Browse hotels and accommodations. Filter by price, rating, amenities, and location to find your perfect stay.
Explore
Discover popular destinations and travel inspiration. See trending places and plan your next adventure.
<ds-tabs>
<button slot="tab">Flights</button>
<button slot="tab">Hotels</button>
<button slot="tab">Explore</button>
<div slot="panel">Flights content...</div>
<div slot="panel">Hotels content...</div>
<div slot="panel">Explore content...</div>
</ds-tabs>
Variants
Two primary tab variants with different visual emphasis and indicator placement.
Primary Tabs
Default tab style with indicator at the bottom. High emphasis for main navigation.
- Use when: tabs are the primary navigation mechanism for a page or view and need strong visual emphasis.
- Avoid when: tabs serve only a secondary filtering role — use Secondary tabs instead to reduce visual competition.
Flights content
Hotels content
Explore content
<ds-tabs>
<button slot="tab">Tab 1</button>
<button slot="tab">Tab 2</button>
...
</ds-tabs>
Secondary Tabs
Lower emphasis variant with indicator at the top for secondary navigation.
- Use when: filtering or sorting content within a section that already uses Primary tabs at a higher level.
- Avoid when: these are the first level of navigation — Primary tabs carry the visual weight that role requires.
Showing all files in your library.
Showing only photo files (.jpg, .png, .gif).
Showing only video files (.mp4, .mov, .avi).
Showing only document files (.pdf, .doc, .txt).
<ds-tabs variant="secondary">
<button slot="tab">Tab 1</button>
<button slot="tab">Tab 2</button>
...
</ds-tabs>
Tabs with Icons
Tabs can include icons alongside labels for better visual
recognition. Mark the icon aria-hidden="true": Material
Symbols draw from ligature text, so a screen reader would otherwise
read "phone Recents".
Your recent calls will appear here.
Your favorite contacts are listed here.
Browse all your contacts.
<ds-tabs>
<button slot="tab">
<span class="material-symbols-outlined" aria-hidden="true">icon</span>
Label
</button>
...
</ds-tabs>
Icon-Only Tabs
Tabs with icons only for compact layouts. Include
aria-label for accessibility.
Home content
Search content
Notifications content
Settings content
<ds-tabs>
<button slot="tab" aria-label="Home">
<span class="material-symbols-outlined">home</span>
</button>
...
</ds-tabs>
Fixed Width Tabs
Tabs that fill available width equally using the
fixed attribute.
Content for tab one.
Content for tab two.
Content for tab three.
<ds-tabs fixed>
<button slot="tab">Tab 1</button>
<button slot="tab">Tab 2</button>
...
</ds-tabs>
States
Tabs support various interactive states.
Disabled Tab
Individual tabs can be disabled using the
disabled attribute:
First tab content.
This tab is disabled.
Third tab content.
<ds-tabs>
<button slot="tab">Active</button>
<button slot="tab" disabled>Disabled</button>
...
</ds-tabs>
Advanced Usage
Programmatic control and advanced tab management:
First panel content.
Second panel content.
Third panel content.
// Set selected tab programmatically
const tabs = document.getElementById('my-tabs');
tabs.selectedIndex = 1;
// Listen for tab changes
tabs.addEventListener('tab-change', (e) => {
console.log('Selected:', e.detail.selectedIndex);
});
API
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
variant |
string | "primary" | Tab style: "primary" or "secondary" |
selected-index |
number | 0 | Index of the currently selected tab |
fixed |
boolean | false | When present, tabs fill available width equally |
scrollable |
boolean | false | Enable horizontal scrolling for many tabs |
Events
| Event | Detail | Description |
|---|---|---|
tab-change |
{ selectedIndex, previousIndex, tab } |
Fired when the selected tab changes |
Slots
| Slot | Description |
|---|---|
tab |
Tab buttons (use <button slot="tab">) |
panel |
Tab panel content (use <div slot="panel">)
|
Keyboard Navigation
| Key | Action |
|---|---|
← / → |
Navigate between tabs |
Home |
Go to first tab |
End |
Go to last tab |
Enter / Space |
Activate focused tab |
Accessibility
Keyboard Interaction
| Key | Context | Expected Result |
|---|---|---|
Tab |
Focus outside tab list | Moves focus to the active tab |
← / → |
Focus on a tab | Moves focus to the previous / next tab |
Home |
Focus on a tab | Moves focus to the first tab |
End |
Focus on a tab | Moves focus to the last tab |
Enter / Space |
Focus on a tab | Activates the focused tab and reveals its panel |
Semantics
-
Tab list uses
role="tablist"; each tab usesrole="tab"; each panel usesrole="tabpanel". -
aria-selectedandaria-controlsare managed automatically. -
Focus is managed via
tabindexso only the active tab is in the tab sequence. - RTL layout is supported.
Usage Guidelines
- When to use: Use tabs to organize content into mutually exclusive views within the same context — for example, filtering a result set or switching between related sections of a page.
- When not to use: Avoid tabs for multi-page routing with distinct URLs. Avoid tabs when fewer than two views are presented, as a single tab provides no navigational value.
- Composition: Choose Primary tabs for top-level main navigation; use Secondary tabs for sub-filtering within a section. Pair each tab with a corresponding panel slot.
-
Common mistakes: Avoid more than five or six tabs
in a single row. Do not use icon-only tabs without an
aria-labelon each button.