はじめに
一覧の表示切り替えを実装するとき、DOM の更新自体は簡単でも、切り替わりが唐突だと操作感が少し硬く見えます。JavaScript でクラスを付け替えて細かくアニメーションを管理する方法もありますが、画面状態が増えるほど調整ポイントが増えがちです。
そんな場面で扱いやすいのが View Transitions API です。document.startViewTransition() で DOM 更新を包むだけで、同一ドキュメント内の状態変化を自然につなげやすくなります。
この記事では、フィルター付きの商品グリッドを題材に、基本の導入から実務向けの応用までをまとめます。
機能やライブラリの概要
View Transitions API は、同一ドキュメント内の UI 切り替えを滑らかに見せるための Web API です。MDN では Document.startViewTransition() を Baseline 2025 の機能として案内しており、最新版ブラウザーでは使いやすさがかなり上がっています。
ポイントは次の3つです。
- DOM の更新処理をそのまま活かしながら、切り替え演出を追加できる
view-transition-nameを使うと、特定要素だけ別アニメーションにできる- 非対応環境では通常の DOM 更新にフォールバックしやすい
従来の「状態切り替えごとに入れ替え用クラスを増やす」実装より、表示更新ロジックとアニメーションの責務を分けやすいのが実務上の利点です。
インストール方法
View Transitions API はブラウザー標準機能なので、ライブラリの追加は不要です。まずは対応ブラウザーを確認したうえで、既存の JavaScript に段階的に組み込むのが安全です。
準備として必要なのは、次の2点です。
document.startViewTransitionの有無を確認してフォールバックを書く- 別スナップショットで動かしたい要素に
view-transition-nameを付ける
基本の使い方
まずは一覧の表示条件を切り替える最小構成です。ボタン押下時に表示対象を変えるだけでも、切り替わりがかなり見やすくなります。
HTML
<div class="filter-bar">
<button type="button" data-filter="all">すべて</button>
<button type="button" data-filter="design">デザイン</button>
<button type="button" data-filter="code">実装</button>
</div>
<section class="item-grid" id="js-item-grid">
<article class="item-card" data-category="design">カード A</article>
<article class="item-card" data-category="code">カード B</article>
<article class="item-card" data-category="design">カード C</article>
</section>
JS
const buttons = document.querySelectorAll("[data-filter]")
const cards = document.querySelectorAll(".item-card")
function updateGrid(filter) {
cards.forEach((card) => {
const visible = filter === "all" || card.dataset.category === filter
card.hidden = !visible
})
}
buttons.forEach((button) => {
button.addEventListener("click", () => {
const filter = button.dataset.filter
if (!document.startViewTransition) {
updateGrid(filter)
return
}
document.startViewTransition(() => {
updateGrid(filter)
})
})
})
この書き方なら、既存の描画更新関数を大きく崩さずに導入できます。まず通常更新を書き、その外側だけ View Transition 対応にする流れが分かりやすいです。
便利な使いどころ
View Transitions API が特に効くのは、次のような UI です。
- 絞り込み付き一覧の表示切り替え
- タブ切り替えとパネル更新
- モーダル内のステップ遷移
- 一覧から詳細への同一ページ内切り替え
共通しているのは、「ページ遷移ではないが、状態変化を少し丁寧に見せたい」場面です。演出を派手にするというより、文脈を途切れさせないための補助として使うと相性が良いです。
応用コード
実務では、カード全体はクロスフェード、見出し画像だけは個別に移動させたいことがあります。そういうときは view-transition-name を使うと整理しやすいです。
HTML
<section class="feature-panel" id="js-feature-panel">
<article class="feature-card is-active" data-view="overview">
<img src="/images/overview.jpg" alt="" class="feature-card__image" />
<h2>概要</h2>
<p>一覧を確認するための説明です。</p>
</article>
<article class="feature-card" data-view="detail" hidden>
<img src="/images/detail.jpg" alt="" class="feature-card__image" />
<h2>詳細</h2>
<p>選択した内容を深掘りするための説明です。</p>
</article>
</section>
CSS
.feature-card__image {
view-transition-name: panel-image;
}
::view-transition-old(panel-image) {
animation: panel-image-out 180ms ease;
}
::view-transition-new(panel-image) {
animation: panel-image-in 260ms ease;
}
@keyframes panel-image-out {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(0.96);
}
}
@keyframes panel-image-in {
from {
opacity: 0;
transform: scale(1.04);
}
to {
opacity: 1;
transform: scale(1);
}
}
JS
const panel = document.querySelector("#js-feature-panel")
const viewButtons = document.querySelectorAll("[data-view-trigger]")
function switchPanel(nextView) {
panel.querySelectorAll(".feature-card").forEach((card) => {
const active = card.dataset.view === nextView
card.hidden = !active
card.classList.toggle("is-active", active)
})
}
viewButtons.forEach((button) => {
button.addEventListener("click", async () => {
const nextView = button.dataset.viewTrigger
if (!document.startViewTransition) {
switchPanel(nextView)
return
}
const transition = document.startViewTransition(() => {
switchPanel(nextView)
})
await transition.finished
})
})
この形にしておくと、状態更新は switchPanel() に閉じ込めたまま、演出だけ CSS 側で調整できます。JavaScript と CSS の役割分担が明確なので、改修時に崩れにくいです。
注意点
- 非対応環境の分岐は必須です
document.startViewTransitionがない環境では通常更新へ落とす前提で組むと安全です。 view-transition-nameは重複管理に注意します
同じ遷移内で意図しない要素まで同名にすると、期待しないアニメーションになることがあります。- 大きな DOM 差し替えは演出より更新設計を先に見直します
すべてを遷移で解決しようとすると、状態管理やアクセシビリティの整理が後回しになりやすいです。 - 動きの量は控えめにします
一覧 UI は操作頻度が高いので、長すぎる演出より短めの補助表現のほうが使いやすいです。
まとめ
View Transitions API は、同一ページ内の表示切り替えを JavaScript 主体で扱いやすくする API です。既存の DOM 更新処理を包むだけで導入を始めやすく、必要なら view-transition-name で要素単位の演出にも広げられます。
まずは絞り込み一覧やタブ切り替えのような、状態変化が明確な UI に入れると効果を判断しやすいです。小さく導入して、効く場面だけ残す進め方が実務では扱いやすいと思います。
ポイント
document.startViewTransition()で既存の DOM 更新処理を包むだけでも導入しやすいview-transition-nameを使うと特定要素だけ別演出にできる- 非対応環境へのフォールバックを先に書くと安全に展開しやすい