MPA のページ遷移を CSS だけで演出する
クライアントルーターを入れず、普通のリンクと普通のページ遷移のまま、一覧の板が詳細の見出しへ動いて見えるか。
デモ
板をクリックすると詳細ページへ移動します。対応ブラウザでは、板がそのまま見出し画像の位置へ動きます。
対応していない場合: リンクは普通に開きます。アニメーションが無いだけで、遷移も表示も何も変わりません。@view-transition は未対応ブラウザでは丸ごと無視される at-rule です。
書いた CSS
ページ遷移のオプトインはこの 1 ルールだけです(src/styles/lab.css)。
@view-transition {
navigation: auto;
}
/* 一覧の板と詳細の見出し画像に、同じ名前を付ける */
/* 一覧: <span style="view-transition-name: art-terrace"> */
/* 詳細: <div style="view-transition-name: art-terrace"> */
@media (prefers-reduced-motion: reduce) {
::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) { animation: none !important; }
} JavaScript は 0 行です。Astro の ClientRouter(旧 ViewTransitions コンポーネント)も入れていません。ブラウザ標準の挙動だけを見るための実験なので、意図的に外しています。
JavaScript で書いた場合との比較
| 観点 | CSS(今回) | クライアントルーター方式 |
|---|---|---|
| 追加する JS | 0 バイト | ルーターのランタイム一式 |
| JS 無効時 | 普通のページ遷移として成立 | 普通のページ遷移に戻る(実装次第) |
| 状態の持ち回り | できない(毎回フルロード) | できる(音声再生の継続など) |
| 壊れ方 | アニメーションが出ないだけ | スクリプトのエラーが遷移そのものを壊しうる |
実運用で使うときの注意
名前の重複は黙って無効になる
view-transition-name が同一ページに 2 つあると、その名前の遷移だけがエラーも警告も無しに効かなくなります。一覧ページでは slug を混ぜて一意にしています。
片方だけの opt-in では効かない
遷移元と遷移先の両方が @view-transition を持つ同一オリジンのときだけ動きます。/lab/ から /blog/ へ出る遷移は従来どおりです(実験の範囲が自然に閉じる)。
一覧側の板は 3 枚、詳細側は 1 枚
行き先に対応する名前が無い要素は、単独で消える扱いになります。今回はそのまま見せています。違和感が出る構図なら、名前を付ける対象を絞る必要があります。
判定を「保留」にした理由
デモとしては動きますが、本体サイトの記事一覧へ入れるかはこれから。記事カードは画像の縦横比がばらつくので、そこで破綻しないか確認してからです。