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.

Go to First Go to Second Go to Third
// 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 uses role="tab"; each panel uses role="tabpanel".
  • aria-selected and aria-controls are managed automatically.
  • Focus is managed via tabindex so 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-label on each button.