ビュートランジション
Astroでは、オプトイン式ページ単位のビュートランジションを数行のコードで実現できます。ビュートランジションは、ブラウザがナビゲーション時に通常おこなうページ全体の更新なしでページコンテンツを更新し、ページ間のシームレスなアニメーションを提供します。
Astroは、単一のページの<head>
に追加可能な<ViewTransitions />
ルーティングコンポーネントを提供しており、これにより別のページに移動する際のページ遷移を制御できます。このコンポーネントは軽量なクライアントサイドルーターを提供し、ナビゲーションをインターセプトしてページ間の遷移をカスタマイズできるようにします。
このコンポーネントを共通のヘッドやレイアウトなど再利用可能な.astro
コンポーネントに追加すると、サイト全体でのアニメーション付きのページ遷移(SPAモード)が可能になります。
Astroのビュートランジションは新しいView TransitionsブラウザAPIによって提供されており、また以下の機能も含みます。
fade
やslide
、none
など、いくつかの組み込みのアニメーションオプション。- 戻る・進むの両ナビゲーションでのアニメーションのサポート。
- トランジションアニメーションのすべての要素を完全にカスタマイズし、さらに独自のアニメーションを作成する機能。
- 非ページへのリンクに対しクライアントサイドナビゲーションを防止するオプション。
- まだView Transition APIをサポートしていないブラウザのためのフォールバック用動作の制御。
prefers-reduced-motion
の自動サポート。
デフォルトでは、すべてのページは通常のフルページのブラウザナビゲーションを使用します。ビュートランジションを有効化すると、ページ単位またはサイト全体で使用できます。
ページにビュートランジションを追加する
セクションタイトル: ページにビュートランジションを追加するViewTransitions />
ルーティングコンポーネントをインポートし、<head>
内に追加することで、ビュートランジションを個別のページで有効化できます。
サイト全体でのビュートランジション(SPAモード)
セクションタイトル: サイト全体でのビュートランジション(SPAモード)<ViewTransitions />
をインポートし、共通の<head>
または共有のレイアウトコンポーネントに追加します。Astroは、旧ページと新ページの類似点に基づいてデフォルトのページアニメーションを作成し、サポートされていないブラウザに対するフォールバック動作も提供します。
以下の例では、このコンポーネントをインポートし<CommonHead />
Astroコンポーネントに追加することで、Astroのデフォルトのページナビゲーションアニメーションをサイト全体に追加しています。これにより、サポートされていないブラウザに対するフォールバック動作も追加されます。
Astroのデフォルトのクライアントサイドナビゲーションを有効にするために、他に必要な設定はありません!
より細かな制御のためには、トランジションディレクティブを使用するか、個々の要素でデフォルトのクライアントサイドナビゲーションをオーバーライドします。
トランジションディレクティブ
セクションタイトル: トランジションディレクティブAstroは、旧ページと新ページの両方に存在する対応する要素に、共通かつ一意のview-transition-name
を自動的に割り当てます。マッチする要素のペアは、要素の種類とDOM内の位置の両方によって推測されます。
.astro
コンポーネント内のページ要素にオプションのtransition:*
ディレクティブを使用すると、ナビゲーション中のページ遷移の動作をより細かく制御できます。
transition:name
: 新旧コンテンツのアニメーションに関するAstroデフォルトの要素のマッチング方式をオーバーライドし、DOM要素のペアを関連付けるトランジション名を指定できます。transition:animate
: アニメーションの種類を指定することで、旧要素を新要素で置き換える際のAstroのデフォルトのアニメーションをオーバーライドできます。Astroの組み込みのアニメーションディレクティブを使用するか、独自のトランジションアニメーションを作成します。transition:persist
: 旧要素を新要素で置き換えるAstroのデフォルトの挙動をオーバーライドし、別のページに移動した際にコンポーネントとHTML要素を保持します。
トランジションに名前を付ける
セクションタイトル: トランジションに名前を付ける場合によっては、対応するビュートランジション要素を自分で特定したい、または特定する必要があるかもしれません。transition:name
ディレクティブを使用して、要素のペアに名前を付けることができます。
transition:name
に使った値は、各ページにつき1回しか使用できないことに注意してください。Astroが適切な名前を自動的に推測できない場合や、要素のマッチングをより細かく制御したい場合に、手動で設定してください。
状態を保持する
セクションタイトル: 状態を保持するastro@2.10.0
transition:persist
ディレクティブを使用すると、ページ間のナビゲーションでコンポーネントとHTML要素を(置き換えるのではなく)保持できます。
たとえば以下の<video>
は、同じvideo要素を含む別のページに移動しても再生され続けます。これは、進む・戻るの両方のナビゲーションで機能します。
Astroアイランド(client:
ディレクティブをもつUIフレームワークコンポーネント)にもディレクティブを配置できます。そのコンポーネントが次のページに存在する場合、旧ページのアイランドは現在の状態のまま表示され、新しいページのアイランドに置き換えられることはありません。
以下の例では、transition:persist
属性をもつ<Counter />
コンポーネントを含むページ間を行き来しても、count
はリセットされません。
また、アイランドあるいは要素が2つのページ間で異なるコンポーネントの中にある場合は、対応する要素を手動で特定できます。
便利な短縮記法として、transition:persist
の値にトランジション名を指定できます。
組み込みのアニメーションディレクティブ
セクションタイトル: 組み込みのアニメーションディレクティブAstroには、デフォルトのfade
トランジションをオーバーライドするための組み込みのアニメーションがいくつか用意されています。transition:animate
ディレクティブを各要素に追加して、特定のトランジションの動作をカスタマイズできます。
fade
(デフォルト): 独自のクロスフェードアニメーションです。旧コンテンツがフェードアウトし、新コンテンツがフェードインします。initial
: Astroの独自のクロスフェードアニメーションを無効にし、ブラウザのデフォルトのスタイルを使用します。slide
: 旧コンテンツが左にスライドアウトし、新コンテンツが右からスライドインするアニメーションです。戻る場合のナビゲーションでは、アニメーションは逆になります。fade
: 旧コンテンツがフェードアウトし、新コンテンツがフェードインするクロスフェードです。none
: ブラウザのデフォルトのアニメーションを無効にします。ページの<html>
要素で使用すると、ページ内のすべての要素のデフォルトのフェードを無効にします。
ページのアニメーションを完全に制御するには、ディレクティブを組み合わせます。<html>
要素でページのデフォルト値を設定し、必要に応じて個々の要素でオーバーライドしてください。
以下の例では、ボディコンテンツにスライドアニメーションを設定し、ページの残りの部分に対してはブラウザのデフォルトのフェードアニメーションを無効にしています。
アニメーションをカスタマイズする
セクションタイトル: アニメーションをカスタマイズする任意のCSSアニメーションプロパティを使用して、トランジションのすべての要素をカスタマイズできます。
組み込みのアニメーションをカスタマイズするには、まずastro:transitions
からアニメーションをインポートし、続いてカスタマイズ用オプションを渡します。
以下の例では、組み込みのfade
アニメーションの継続時間(duration)をカスタマイズしています。
また、transition:animate
で独自のアニメーションも定義できます。進む・戻るの挙動と新旧のページについて、以下の型に従って定義します。
以下の例は、独自のfade
アニメーションを定義するために必要なすべてのプロパティを示しています。
クライアントサイドナビゲーションの防止
セクションタイトル: クライアントサイドナビゲーションの防止<ViewTransitions />
コンポーネントを追加してページでクライアントサイドルーティングを有効にすると、サイト内の別のページにリンクするページ内のすべてのアンカーは、クライアントサイドルーティングによってナビゲートされます。ただ、クライアントサイドルーティングでナビゲートしたくないような場合もあります。たとえば、public/
フォルダ内のPDFや、画像を生成するAPIルートなどの非ページへのリンクです。
こうした場合、data-astro-reload
属性を使用して、リンクごとにクライアントサイドルーティングをオプトアウトできます。
これらのリンクはルーターによって無視され、フルページのナビゲーションが発生します。
フォールバックの制御
セクションタイトル: フォールバックの制御<ViewTransitions />
ルーターは、ビュートランジションをサポートするブラウザ(すなわちChromiumブラウザ)で最も有効に機能しますが、他のブラウザに対するデフォルトのフォールバックサポートも含んでいます。ブラウザがView Transitions APIをサポートしていなくても体験を損なわないように、Astroはフォールバックオプションのいずれかを使用してブラウザ内でのナビゲーションを提供します。
<ViewTransitions />
コンポーネントにfallback
プロパティを追加し、swap
またはnone
に設定することで、Astroのデフォルトのフォールバックサポートをオーバーライドできます。
animate
(デフォルト、推奨) - Astroは、ページコンテンツを更新する前に、カスタム属性を使用してビュートランジションをシミュレートします。swap
- Astroはページのアニメーションを試みません。代わりに、旧ページはすぐに新しいページに置き換えられます。none
- Astroはアニメーションによるページ遷移を一切おこないません。代わりに、サポート外のブラウザではフルページのナビゲーションがおこなわれます。
initial
ブラウザアニメーションはAstroによってシミュレートされません。そのため、このアニメーションを使用する要素は現在アニメーションされません。
クライアントサイドナビゲーションの流れ
セクションタイトル: クライアントサイドナビゲーションの流れ<ViewTransitions />
ルーターを使用すると、以下の流れでAstroのクライアントサイドナビゲーションが実行されます。
-
サイト訪問者が以下のいずれかのアクションを実行し、ナビゲーションがトリガーされる。
- サイト内の別のページへ内部リンクする
<a>
タグをクリックする。 - 戻るボタンをクリックする。
- 進むボタンをクリックする。
- サイト内の別のページへ内部リンクする
-
ルーターが次のページの取得を開始する。
-
ルーターが、
'forward'
または'back'
の値をもつdata-astro-transition
属性をHTML要素に追加する。 -
ルーターが
document.startViewTransition
をコールする。これにより、ブラウザのview transition processがトリガーされる。重要なこととして、ブラウザはページの現在の状態をスクリーンショットする。 -
startViewTransition
コールバック内で、ルーターがswapを実行する。これは以下の一連のイベントから構成される。-
<head>
のコンテンツが、いくつかの要素を残して入れ替わる。- FOUCを防止するために、スタイルシートのDOMノードが新しいページに存在する場合は残される。
- 新しいページにスクリプトが存在する場合は残される。
- 新しいページに対応する要素がある場合、
transition:persist
をもつ他のhead要素は残される。
-
<body>
は、新しいページのbodyに完全に置き換えられる。 -
transition:persist
とマークされた要素が新しいページに存在する場合、新しいDOMに移動する。 -
必要に応じてスクロール位置が復元される。
-
astro:after-swap
イベントがdocument
でトリガーされる。これがswapプロセスの終わりとなる。
-
-
ルーターが、トランジションを解決する前に新しいスタイルシートのロードを待つ。
-
ルーターが、ページに追加された新しいスクリプトを実行する。
-
astro:page-load
イベントが発火する。これがナビゲーションプロセスの終わりとなる。
ページナビゲーション中のスクリプトの動作
セクションタイトル: ページナビゲーション中のスクリプトの動作<ViewTransitions />
コンポーネントを使用してページ間をナビゲートする際、ブラウザの動作に合わせてスクリプトが順に実行されます。
グローバルな状態を設定しているコードがある場合は、そのスクリプトが複数回実行される可能性があることを考慮する必要があります。<script>
タグでグローバルな状態をチェックし、可能な限り条件付きでコードを実行してください。
モジュールスクリプトは、ブラウザがロード済みのモジュールを追跡しているため、常に1回だけ実行されます。これらのスクリプトでは再実行の心配は必要ありません。
astro:page-load
セクションタイトル: astro:page-load新しいページがユーザーに表示され、ブロッキングスタイルとスクリプトがロードされたあとの、ページナビゲーションの最後に発生するイベントです。document
でこのイベントをリッスンできます。
<ViewTransitions />
コンポーネントは、初回のページナビゲーション(MPA)と、その後の進む・戻るのナビゲーションの両方でこのイベントを発生させます。
このイベントを使用すると、すべてのページナビゲーションでコードを実行したり、あるいは1度だけ実行したりできます。
astro:after-swap
セクションタイトル: astro:after-swap旧ページが新ページに置き換わった直後に発生するイベントです。document
でこのイベントをリッスンできます。
このイベントは、新しいページに引き継ぐ必要があるDOM上の状態を復元するのに役立ちます。
たとえばダークモードのサポートを実装している場合、このイベントを使用してページロード間で状態を復元できます。
prefers-reduced-motion
セクションタイトル: prefers-reduced-motionAstroの<ViewTransitions />
コンポーネントにはCSSメディアクエリが含まれており、prefer-reduced-motion
の設定が検出された場合、フォールバックアニメーションを含むすべてのビュートランジションアニメーションが無効になります。代わりに、ブラウザはアニメーションなしでDOM要素を単純に入れ替えます。
v2.xからv3.0へのアップグレード
セクションタイトル: v2.xからv3.0へのアップグレードAstro v3.0では、ビュートランジションを使うために実験的なフラグは不要となりました。
Astro 2.xでこの実験的なフラグを有効にしていなかった場合、プロジェクトへの破壊的な変更はありません。新しいビュートランジションAPIは、既存のコードに影響を与えません。
実験的なビュートランジションを使用していた場合、以前のバージョンからAstroプロジェクトをアップグレードする際に、いくつかの破壊的な変更が発生する可能性があります。
experimental.viewTransitions: true
が設定されたAstro v2.xプロジェクトをv3.0にアップグレードするためには、以下の手順に従ってください。
experimental.viewTransitions
からのアップグレード
セクションタイトル: experimental.viewTransitionsからのアップグレードビュートランジションの実験的なフラグを有効にしていた場合、Astro v3.0ではデフォルトでビュートランジションが有効になっているため、プロジェクトを更新する必要があります。
experimental.viewTransitions
フラグの削除
セクションタイトル: experimental.viewTransitionsフラグの削除実験的なフラグを削除します。
インポートソースの更新
セクションタイトル: インポートソースの更新<ViewTransitions />
コンポーネントはastro:components
からastro:transitions
に移動しました。プロジェクト内のすべてのインポートソースを更新してください。
transition:animate
ディレクティブの更新
セクションタイトル: transition:animateディレクティブの更新変更: transition:animate
の値morph
はinitial
へとリネームされました。また、これはデフォルトのアニメーションではなくなりました。transition:animate
ディレクティブが指定されていない場合、アニメーションはデフォルトでfade
になります。
-
morph
アニメーションをinitial
にリネームします。 -
デフォルトの
morph
を使っていたアニメーションを維持するには、transition:animate="initial"
を明示的に追加します。 -
明示的に
fade
に設定されていたアニメーションは安全に削除できます。これは現在デフォルトの動作となりました。
追加: Astroはtransition:animate
の値として新たにnone
をサポートしました。この値をページの<html>
要素に使用すると、ページ全体のアニメーションを無効にできます。これにより、アニメーションディレクティブをもたないページ要素のデフォルトのアニメーションがオーバーライドされます。個々の要素にアニメーションを設定することはでき、指定したアニメーションが実行されます。
-
個々のページでデフォルトのトランジションをすべて無効にし、
transition:animate
ディレクティブを明示的に使用している要素のアニメーションだけを有効化できます。
イベント名の更新
セクションタイトル: イベント名の更新astro:load
イベントはastro:page-load
にリネームされました。プロジェクト内でこのイベント名を使っているすべての箇所をリネームしてください。
astro:beforeload
イベントはastro:after-swap
にリネームされました。プロジェクト内でこのイベント名を使っているすべての箇所をリネームしてください。