material-tabs

MD3 tabs — primary & secondary variants, fixed or scrollable, optional icons + badges; anchor or button mode.

Primary tabs — icon + label (64dp)

Equal-width fixed tabs. Icons stack above labels. Active indicator is 3dp tall, top-rounded, hugs the label/icon column with a 24dp minimum. Trips carries a count badge; Explore shows a small dot for unread state.

Primary above secondary

Secondary tabs sit below primary tabs to establish hierarchy within a section. Their indicator is 2dp tall and spans the full tab width.

Scrollable

When the set won't fit on screen, opt in via scrollable. Tabs use intrinsic widths and the first tab is offset by 52dp from the leading edge.

Anchor mode — deep links

Pass href to render a tab as <a>. The browser handles navigation; materialTabSelect still fires for SPA routers (React) and server-driven frameworks (Unpoly, HTMX).

Disabled state

Disabled tabs are skipped by Arrow / Home / End focus traversal.

No initial selection

When no tab carries selected, the first enabled tab is auto-selected on mount so the indicator is never hidden.

Cancelable selection

materialTabSelect is cancelable — a listener can call preventDefault() to veto the switch and keep the previous tab selected. Try "Locked" below.

Selection log

(none)
Sample usage
<!-- Primary tabs with icons + a count badge -->
<material-tabs>
  <material-tab value="flights" label="Flights" icon="flight" selected></material-tab>
  <material-tab value="trips" label="Trips" icon="luggage">
    <material-badge slot="badge" value="3"></material-badge>
  </material-tab>
  <material-tab value="explore" label="Explore" icon="explore"></material-tab>
</material-tabs>

<!-- Secondary tabs, label only -->
<material-tabs variant="secondary">
  <material-tab value="all" label="All" selected></material-tab>
  <material-tab value="recent" label="Recent"></material-tab>
</material-tabs>

<!-- Scrollable -->
<material-tabs scrollable>…</material-tabs>

<!-- Anchor mode (browser handles navigation; event still fires) -->
<material-tabs>
  <material-tab href="#flights" label="Flights" selected></material-tab>
</material-tabs>

<script>
  document.querySelector('material-tabs').addEventListener('materialTabSelect', e => {
    console.log(e.detail.value);
  });
</script>