Animated Tab Switch with View Transitions

Cross-fade between tab panels and animate the active-tab indicator pill smoothly across the tab bar using a single shared view-transition-name.

UI Patterns

Detailed Explanation

Two Animations, One Transition

A polished tab UI has two synchronized animations: (1) the active-tab indicator pill sliding to the new tab, and (2) the panel content cross-fading. Both fall out of a single startViewTransition call.

<div class="tabs">
  <button class="tab" data-active="true">A</button>
  <button class="tab">B</button>
  <div class="indicator"></div>
</div>
<div class="panel">…content for active tab…</div>
.indicator {
  view-transition-name: tab-indicator;
}
.panel {
  view-transition-name: tab-panel;
}
function selectTab(target) {
  document.startViewTransition(() => {
    document.querySelectorAll('.tab').forEach(t => t.dataset.active = 'false');
    target.dataset.active = 'true';
    moveIndicatorTo(target); // sets .indicator's left + width
    swapPanelContent(target.dataset.panelId);
  });
}

The browser captures the indicator at its old position, animates the snapshot to the new position, and cross-fades the panel content in parallel. No FLIP math required.

Why this beats CSS transition: left, width

A pure CSS transition on the indicator works only if you keep the same DOM element across renders. As soon as you re-render the tab list (common in React when filtering tabs), the transition resets. View Transitions snapshot the visual position regardless of DOM identity, so re-renders animate correctly.

Performance: keep the panel content lightweight

Snapshotting a panel with thousands of DOM nodes is slower than snapshotting a panel with a hundred. If the panel contains a virtualized list, scroll position will reset on re-render — capture it before the transition and restore after transition.finished.

Use Case

Settings UIs, dashboards with metric panels, code editors with file tabs, browsers' devtools panels, and any tabbed interface where you want both indicator and content animations without writing FLIP code.

Try ItView Transitions API Generator

Open full tool