📘

古き良きMPAの画面還移をSPAっぽくする

2024/11/27に公開

サマリー

ややこしいSPAフレームワークが大嫌いな皆様へのちょっとした朗報。
View Transitions APIという便利なものがあり、MPA(Multi-Page-Application)における同一オリジンでの別ページへの遷移にアニメーションを付与できる。
https://developer.mozilla.org/ja/docs/Web/API/View_Transitions_API

  • 完全に異なるDOM要素同士でもトランジションが付与できる(前ページでの<img>タグが<span>タグに変化する、などといった画面遷移も作れる)
  • CSS3のアニメーションAPIをフル活用して様々なトランジションが柔軟に作成できる
  • 特定の要素のみをトランジションもしくはページ遷移そのものから除外することも可能

などといった痒い所に手が届くCSSらしくない特徴が軽く話題。正直もっと話題になっていいと思う。

使い方

1 / View Transitions APIの有効化

@view-transition {
  navigation: auto;
}

これだけ。
非常にシンプルである。

2 / カスタマイズ

デフォルトは単純なフェードインとなるが、よりこだわったトランジションを実装したい場合::view-transition-(old|new)擬似要素を使う。

@keyframes grow-x {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

@keyframes shrink-x {
  from {
    transform: scaleX(1);
  }
  to {
    transform: scaleX(0);
  }
}

::view-transition-old(figure-caption) {
  animation: 0.25s linear both shrink-x;
}

::view-transition-new(figure-caption) {
  animation: 0.25s 0.25s linear both grow-x;
}

具体例はこのようなものである。(サンプルコードをMDN公式より引用)
filterプロパティをはじめCSS3の基本的な機能は全て使えるため、非常に詳細かつ高クオリティなトランジションを楽に作れる。

3 / 特定の要素を除外する

先ほどの例の応用、というか単純化。

::view-transition-old(#sidebar) {
  animation: none;
  display: none;
}

::view-transition-new(#sidebar) {
  animation: none;
}

このような記述をすると読み込みが完了した時点で#sidebar要素のみが最優先でレンダリングされ、置き換えられるようになる。
これの応用でMPA技術のみの擬似的なSPAが作れる。正直古のframeタグの延長みたいなUXなので早く廃れてほしい。

ちなみに、

::view-transition-old(#sidebar) {
  animation: none;
}

::view-transition-new(#sidebar) {
  animation: none;
  display: none;
}

このようにdisplay:noneの位置を逆転させると、完全に読み込みと遷移、JSなどの実行が全て完了するまで#sidebar要素のみレンダリングが先延ばしされる。
これもどこかで使い道があると思う。

Discussion