← Back to gallery
CSS

Animated Tabs

Three opinionated tab indicator animations — Underline Slide (a thin underline that translates across active tabs as the most-used baseline), Pill Tab (an iOS-style filled rounded pill that slides under the active label), and Notch Indicator (a Material-style bottom notch + dot that travels). Each one is driven by container-level custom properties via :has() with a class-toggle fallback for browsers without :has() support.

tab-barunderline-slidepill-tabnotcharia-selectedcustom-properties

Active-tab indicator · :has() driven

Animated Tabs

Three production tab-indicator animations — Underline Slide (a thin underline that translates across active tabs), Pill Tab (an iOS-style filled rounded pill that slides under the active label), and Notch Indicator (a Material-style bottom dot + bar that travels). Each one is driven by container-level custom properties via :has() so the indicator position updates without JavaScript when the active tab changes; a class-toggle fallback covers browsers without :has().

Baseline · thin underline translates

Underline Slide

The most-used tab indicator: a thin underline (2px) that translates across the active tab. Width = 100/N% so it always matches the slot. The slide is composited via transform: translateX, so the indicator stays butter-smooth even with text-heavy tabs.

  • translateX
  • 2px underline
  • baseline

iOS · filled rounded pill

Pill Tab

iOS-style segmented tab where the active tab is highlighted with a full-height pill background that slides between slots. Active label brightens against the pill; inactive labels stay dim. The pill itself has a soft accent glow to lift it off the bar.

  • filled pill
  • active label brightens
  • iOS-style

Material · bottom dot + bar

Notch Indicator

Material-style indicator: a small dot + a thin bar at the bottom of the active tab. The dot is the saturated accent; the bar is a subtle anchor that frames the dot. The whole indicator block translates between tab centres.

  • bottom dot
  • thin bar
  • Material-style

Tab indicator inspector

Underline Slide

Underline · 2px
Underline Slide
  • translateX
  • 2px underline
  • baseline

The most-used tab indicator: a thin underline (2px) that translates across the active tab. Width = 100/N% so it always matches the slot. The slide is composited via transform: translateX, so the indicator stays butter-smooth even with text-heavy tabs.

/* Thin 2px underline translates across the active tab via translateX(--tab-active × 100%). */
.tab-bar {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

.tab-bar input { position: absolute; opacity: 0; pointer-events: none; }
.tab-bar label { padding: 12px 14px; text-align: center; cursor: pointer; }
.tab-bar input:checked + label { color: #7dd3fc; }

.tab-bar::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: calc(100% / 4);
  height: 2px;
  background: #7dd3fc;
  transform: translateX(calc(100% * var(--tab-active, 0)));
  transition: transform 0.26s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* :has() drives --tab-active from the checked radio's index. */
.tab-bar:has(input:nth-of-type(2):checked) { --tab-active: 1; }
.tab-bar:has(input:nth-of-type(3):checked) { --tab-active: 2; }
.tab-bar:has(input:nth-of-type(4):checked) { --tab-active: 3; }