MPA で使う(クロスドキュメント遷移)
マルチページサイトでも、普通の <a href> や location 遷移に
View Transition を載せられる。Astro / Hugo / 静的サイト / 普通のサーバーレンダリングサイト全部に使える。
この learn-tech のような静的サイトはまさにこれ。
有効化は CSS の1行
同一オリジンへのナビゲーションに対して、ブラウザが自動で transition を挟むようになる。
@view-transition {
navigation: auto;
}
navigation: auto = 同一オリジンの普通のナビゲーション(リンククリック、フォーム submit、
history.back() 等)で transition を発火する。
navigation: none がデフォルト(無効)。
クロスオリジンへの遷移では発火しない。同じオリジン内のページ間でしか動かない。
サブドメイン違いでもダメ(blog.example.com → www.example.com は不可)。
同じ name で hero 遷移
ページ A とページ B の両方で同じ view-transition-name を持つ要素を置けば、
その要素は別ページ間でもモーフする。
<a href="/blog/post-3.html">
<img class="thumb" src="post-3.jpg" style="view-transition-name: post-3-image" />
</a>
<img class="hero" src="post-3.jpg" style="view-transition-name: post-3-image" />
ブラウザはページAでスナップショットを撮り、ナビゲーション後にページBでスナップショットを撮って繋ぐ。 JS は一切要らない。
イベントで挙動をいじる
クロスドキュメント transition では、専用の2つのイベントを使ってアニメをカスタマイズできる。
| イベント | 発火タイミング | 役割 |
|---|---|---|
pageswap |
遷移元のページが消える直前 | 遷移元側で見せる「お別れ」アニメや、name の動的設定 |
pagereveal |
遷移先のページが描画されてアニメが始まる直前 | 遷移先側のアニメ調整、active types の確認 |
window.addEventListener("pageswap", (e) => {
if (!e.viewTransition) return // transition が走らないナビゲーション
const from = new URL(e.activation.from.url)
const to = new URL(e.activation.entry.url)
// 例: 詳細から一覧に戻るときは別の名前を使いたい
if (to.pathname === "/blog/" && from.pathname.startsWith("/blog/")) {
document.querySelector(".hero")?.style.setProperty("view-transition-name", "post-image")
}
})
window.addEventListener("pagereveal", (e) => {
if (!e.viewTransition) return
const nav = navigation.activation
if (nav.navigationType === "traverse" && isBack(nav)) {
e.viewTransition.types.add("back")
} else {
e.viewTransition.types.add("forward")
}
})
types を付けたら CSS で
html:active-view-transition-type(forward) のように分岐すればよい。
詳しくは CSS と疑似要素 を参照。
「進む / 戻る」をブラウザの状態で判定
pagereveal 内でナビゲーション方向を取るには navigation.activation を使う。
function isBack(activation) {
// 戻るナビゲーション(traverse)かつ現在のエントリより前
return activation.navigationType === "traverse"
&& activation.entry.index < (activation.from?.index ?? 0)
}
SPA と MPA を併用する
Astro の <ClientRouter /> や同種のライブラリは「MPA だけど内部では fetch + DOM 入れ替え」で
SPA 風に動く。結果として両方のメリットを取れるのが View Transition の強み。
- 初回ロードはサーバーから普通に HTML が返る
- 遷移時はライブラリが
fetch+startViewTransitionで繋ぐ - クライアントの View Transition 非対応時は普通の遷移にフォールバック
このサイト(learn-tech)に試しに足してみる
assets/style.css に1行足すだけで、ページ間遷移にデフォルトのクロスフェードが付く。
@view-transition { navigation: auto; }
ロゴやナビ要素に view-transition-name を当てれば、
ヘッダがフラッシュせずそのまま居続けるような挙動も作れる。