Skip to main content brightness_auto motion_photos_off palette download more_vert
toc

Tabs

Tabs organize groups of related content that are at the same level of hierarchy.

Flights Trips Explore
<md-gb-tabs aria-label="Travel">
  <md-gb-tab selected><span slot="label">Flights</span></md-gb-tab>
  <md-gb-tab><span slot="label">Trips</span></md-gb-tab>
  <md-gb-tab><span slot="label">Explore</span></md-gb-tab>
</md-gb-tabs>

Install with shadcn/ui: npx shadcn@latest add https://material-web.dev/3.0/r/md-tabs.json (setup)

  • Same level of hierarchy. Tabs switch between views of related content that are peers. Don't use them for steps in a flow.
  • Primary or secondary. Primary tabs sit at the top of the content under a top app bar and show the main destinations. Secondary tabs split a content area further. Use one type in a bar.
  • Short labels. Keep labels to a word or two. Use icons only when they are simple and recognizable.
  • Avoid dense tabs by default. Lowering the density shrinks the targets below 48px, so let people opt in.

A tab list holds tabs, and each tab has an optional icon, a label and an optional badge. Tab panels hold the content.

inbox Inbox 3 send Sent
Three new messages.
Messages you sent.
<md-gb-tabs id="anatomy-tabs" aria-label="Mail">
  <md-gb-tab selected>
    <md-gb-icon>inbox</md-gb-icon>
    <span slot="label">Inbox</span>
    <span class="badge badge-large tab-badge" slot="badge">3</span>
  </md-gb-tab>
  <md-gb-tab>
    <md-gb-icon>send</md-gb-icon>
    <span slot="label">Sent</span>
  </md-gb-tab>
</md-gb-tabs>
<md-gb-tab-panels for="anatomy-tabs">
  <div role="tabpanel">Three new messages.</div>
  <div role="tabpanel">Messages you sent.</div>
</md-gb-tab-panels>

Tabs are primary by default. Set variant="secondary" for secondary tabs, which put the icon beside the label.

flight Travel hotel Hotel
<md-gb-tabs variant="secondary" aria-label="Trip type">
  <md-gb-tab selected>
    <md-gb-icon>flight</md-gb-icon>
    <span slot="label">Travel</span>
  </md-gb-tab>
  <md-gb-tab>
    <md-gb-icon>hotel</md-gb-icon>
    <span slot="label">Hotel</span>
  </md-gb-tab>
</md-gb-tabs>

Put an icon before the label, or leave out the label for icon-only tabs. Icon-only tabs need an aria-label.

flight Flights luggage Trips photo videocam
<md-gb-tabs aria-label="Travel">
  <md-gb-tab selected>
    <md-gb-icon>flight</md-gb-icon>
    <span slot="label">Flights</span>
  </md-gb-tab>
  <md-gb-tab>
    <md-gb-icon>luggage</md-gb-icon>
    <span slot="label">Trips</span>
  </md-gb-tab>
</md-gb-tabs>
<md-gb-tabs aria-label="Media">
  <md-gb-tab selected aria-label="Photos"><md-gb-icon>photo</md-gb-icon></md-gb-tab>
  <md-gb-tab aria-label="Videos"><md-gb-icon>videocam</md-gb-icon></md-gb-tab>
</md-gb-tabs>

A tab can show a badge in the badge slot for counts or status.

Inbox 3 Sent
<md-gb-tabs aria-label="Mail">
  <md-gb-tab selected>
    <span slot="label">Inbox</span>
    <span class="badge badge-large tab-badge" slot="badge">3</span>
  </md-gb-tab>
  <md-gb-tab><span slot="label">Sent</span></md-gb-tab>
</md-gb-tabs>

Link each tab to its panel with tabpanel, the id of a panel such as md-aria-tabpanel. Only the selected panel is shown.

Flights Trips Search one-way and round-trip fares. Your upcoming and past bookings.
<md-gb-tabs aria-label="Travel">
  <md-gb-tab selected tabpanel="flights-panel"><span slot="label">Flights</span></md-gb-tab>
  <md-gb-tab tabpanel="trips-panel"><span slot="label">Trips</span></md-gb-tab>
</md-gb-tabs>
<md-aria-tabpanel id="flights-panel">Search one-way and round-trip fares.</md-aria-tabpanel>
<md-aria-tabpanel id="trips-panel">Your upcoming and past bookings.</md-aria-tabpanel>

md-gb-tab-panels holds the panels next to the tabs and lets people swipe between them. It pairs with the previous tab list, or with for, the id of one. Set gestures-disabled to turn swiping off.

Flights Trips Explore
Search one-way and round-trip fares.
Your upcoming and past bookings.
Ideas for your next destination.
<md-gb-tabs id="places" aria-label="Places">
  <md-gb-tab selected><span slot="label">Flights</span></md-gb-tab>
  <md-gb-tab><span slot="label">Trips</span></md-gb-tab>
  <md-gb-tab><span slot="label">Explore</span></md-gb-tab>
</md-gb-tabs>
<md-gb-tab-panels for="places">
  <div role="tabpanel">Search one-way and round-trip fares.</div>
  <div role="tabpanel">Your upcoming and past bookings.</div>
  <div role="tabpanel">Ideas for your next destination.</div>
</md-gb-tab-panels>

Fixed tabs share the width equally. Set scrollable to size each tab to its label and scroll the bar when they overflow.

Flights Trips Hotels Car rental Things to do
<md-gb-tabs scrollable aria-label="Travel">
  <md-gb-tab selected><span slot="label">Flights</span></md-gb-tab>
  <md-gb-tab><span slot="label">Trips</span></md-gb-tab>
  <md-gb-tab><span slot="label">Hotels</span></md-gb-tab>
  <md-gb-tab><span slot="label">Car rental</span></md-gb-tab>
  <md-gb-tab><span slot="label">Things to do</span></md-gb-tab>
</md-gb-tabs>

Set density from 0 (default) to -3 to remove 4px of height per step.

Flights Trips
<md-gb-tabs density="-2" aria-label="Travel">
  <md-gb-tab selected><span slot="label">Flights</span></md-gb-tab>
  <md-gb-tab><span slot="label">Trips</span></md-gb-tab>
</md-gb-tabs>

The tab list fires change when a person picks a tab. Read the new tab from selectedTabIndex.

HTMLJS
<md-gb-tabs aria-label="Travel">
  <md-gb-tab selected><span slot="label">Flights</span></md-gb-tab>
  <md-gb-tab><span slot="label">Trips</span></md-gb-tab>
  <md-gb-tab><span slot="label">Explore</span></md-gb-tab>
</md-gb-tabs>
<output>Selected tab: 0</output>
  • Tabs use the tablist, tab and tabpanel roles. Label the tab list with aria-label or aria-labelledby, and give icon-only tabs an aria-label.
  • The list is one tab stop. The arrow keys move between tabs, and Space or Enter selects the focused one.
  • Each tab controls a panel, and each panel is labelled by its tab. Linking them with tabpanel or md-gb-tab-panels does this for you.
Material Design 3Spec checked73% tokens

87 of 206 buildable spec units are tested, 12 are excluded with a written reason and 0 are uncovered (the target is 0). 41 of 56 token declarations match the spec (73%), and 15 have no spec token.

BaselineWidely availableChrome 124Edge 124Firefox 125Safari 17.4

The component’s own CSS and JavaScript rely only on web platform features that are Baseline widely available: it works in Chrome 124, Edge 124, Firefox 125, Safari 17.4 and later.

Newer features it uses where the browser has them (progressive enhancements):

WAI-ARIAaxe and ARIA 1.3 passButtonTabs

Roles the component renders: button (opens in a new tab), tab (opens in a new tab), tablist (opens in a new tab), tabpanel (opens in a new tab).

Follows the WAI-ARIA Authoring Practices: Button (opens in a new tab), Tabs (opens in a new tab).

5 rendered states run through axe-core and the WAI-ARIA 1.3 role and attribute rules in a real browser, with no known gaps.

Lighthouse99 · 100 · 100 · 100
  • Performance
  • Accessibility
  • Best practices
  • SEO

Audits under 90:

  • Eliminate render-blocking resources
  • Minify JavaScript
  • Enable text compression
  • Network dependency tree
  • Render blocking requests

Lighthouse 12.8.2 (desktop, 2026-11-08) on the component alone: its first example on a page of its own, without this site's shell. The modules are the development build (not bundled or minified), so the performance score is indicative.

A Material Design tab component.

Property Attribute Type Default
selected
Whether the tab is selected.
selected boolean
tabpanel
ID of the associated md-aria-tabpanel element.
tabpanel string
Slot Description
default Used to display an optional leading icon, such as <md-gb-icon>. Icons are unclassed; the tab sets --md-icon-* for them.
badge Used to display an optional badge, such as <span class="badge tab-badge">.
label Used to display the tab's label. <span class="tab-label"> in the default slot is equivalent. Bare text is not supported.
Property Description
--badge-space
--focus-indicator-clearance
--focus-indicator-inset
--focus-indicator-shape
--icon-badge-inset
--icon-color
--icon-label-space
--icon-size
--label-text
--label-text-axes
--label-text-color
--label-text-tracking
--leading-space
--stacked-icon-label-space
--tab-scroll-margin
--trailing-space

The swipeable content panels of a set of Material Design tabs.

Property Attribute Type Default
gesturesDisabled
Whether to turn off swiping between panels.
gestures-disabled boolean false
htmlFor
The id of the <md-gb-tabs> these panels belong to.
for string ''
Slot Description
default The tab panels: elements with role="tabpanel", such as <md-aria-tabpanel> or <div role="tabpanel">.
Property Description
--transition-duration Duration of a slide between panels.
--transition-easing Easing of a slide between panels.

A Material Design tabs component.

Property Attribute Type Default
align
Where fixed tabs sit when the window is wider than compact: center (default) or start, the leading edge. tabs.md, Responsive layout: "The group of tabs should use a fluid margin and align to the center or leading edge of the body region." At compact windows the tabs fill the full width.
align "start" "center"
autoSelect
Whether or not to automatically select a tab when it is focused.
autoselect boolean false
density
The density, from 0 (default) to -3. Each step down removes 4px from the tabs' height (48px, or 64px with icon and label); values are clamped to that range. tabs.md "Avoid applying density by default": dense tabs are below the 48x48 CSS pixel target, so let people opt in (a denser layout or theme) and keep the controls that change it at 48x48.
density Density
orientation
Orientation of the tablist ('horizontal' or 'vertical').
orientation "horizontal" "vertical"
scrollable
Scrollable tabs: each tab's width is defined by its label (tabs.md) rather than every tab taking the width of the widest, and the bar scrolls when they overflow. Fixed tabs (the default) are equal.
scrollable boolean false
scrollBehavior
How the tabs react to scrolling: hide scrolls them off the screen when the page scrolls down and returns them when it scrolls up (tabs.md). Tabs attached to an app bar (its tabs slot) leave this unset: the app bar moves them with itself as one unit.
scroll-behavior "hide"
scrollTarget
The id of the element whose scrolling drives scroll-behavior. Defaults to the window.
scroll-target string ''
selectedTabIndex
The index of the currently selected tab.
selectedtabindex number
variant
The visual variant of the tabs.
variant TabsVariant 'primary'
Slot Description
default Used to display <md-gb-tab> children.
Property Description
--active-indicator-color
--active-indicator-height
--active-indicator-inset
--active-indicator-min-length
--active-indicator-shape
--container-color
--container-height
--container-shape
--density-step Tab height removed per density step.
--divider-color
--divider-thickness
Install Material Web 3.0

Your browser did not offer to install the docs as an app. Install them from the browser instead:

Close
Send feedback
Bug Documentation Idea

Opens a new GitHub issue for material-components/material-web in a new tab, with this filled in.

Cancel Open issue