View Transitions によるタブ切替アニメーション

タブパネル間のクロスフェードと、タブバー上のアクティブタブインジケータのスムーズな移動を、共通の view-transition-name 1つで実現。

UI Patterns

詳細な説明

2つのアニメーション、1つのトランジション

洗練されたタブ UI には2つの同期アニメーションがあります: (1) アクティブタブの インジケータピル が新タブへスライド、(2) パネルコンテンツ のクロスフェード。両方が startViewTransition 1回呼び出しから自然に得られます。

<div class="tabs">
  <button class="tab" data-active="true">A</button>
  <button class="tab">B</button>
  <div class="indicator"></div>
</div>
<div class="panel">…アクティブタブのコンテンツ…</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); // .indicator の left + width を設定
    swapPanelContent(target.dataset.panelId);
  });
}

ブラウザは古い位置のインジケータをキャプチャし、スナップショットを新しい位置までアニメーションし、パネルコンテンツのクロスフェードを並行して実行します。FLIP 計算は不要です。

CSS transition: left, width より優れている理由

純粋な CSS transition でインジケータをアニメーションするには、再描画間で同じ DOM 要素を維持する必要があります。タブリストを再描画した瞬間(React で頻発、特にタブをフィルタするとき)transition がリセットされます。View Transitions は DOM の同一性に依らず視覚位置 をスナップショットするため、再描画でも正しくアニメーションします。

パフォーマンス:パネルコンテンツを軽量に

数千の DOM ノードを持つパネルのスナップショットは、数百のパネルより遅くなります。仮想化リストを含む場合、再描画でスクロール位置がリセットされます。トランジション前にキャプチャし、transition.finished 後に復元してください。

ユースケース

設定 UI、メトリクスパネルを持つダッシュボード、ファイルタブを持つコードエディタ、ブラウザ DevTools のパネル、FLIP コードを書かずにインジケータとコンテンツの両方をアニメーション化したいタブインターフェース全般。

試してみるView Transitions API ジェネレーター

フルツールを開く