言語を切り替える
テーマを切り替える

Astro View Transitions:2 行のコードで Web サイトにアプリのような滑らかな体験を

Astro でブログを丁寧に作り、デザインもレイアウトもこだわったのに、リンクをクリックすると画面が一瞬真っ白になり、それから新しいページが読み込まれる——そんな経験はありませんか? iPhone の滑らかなアニメーションから、Windows 98 のような無骨な画面切り替えに戻された気分になります。

昨年、知人の Web サイト制作を手伝っていたとき、別のポートフォリオを見て「なぜあっちはプロジェクトをクリックすると画像が滑らかに拡大するのに、うちはただ再読み込みされるの?」と聞かれました。React で SPA に作り直すしかないのか、Astro の静的生成の強みを捨てるのか——少し気まずく感じました。

そこで出会ったのが View Transitions API と Astro の組み合わせです。初めて試したときは本当に驚きました。Layout コンポーネントの <head> に 2 行足すだけで、ページ切り替えが滑らかな遷移アニメーションに変わったのです。React も Vue も不要、JavaScript ライブラリすら要りません。

本記事では次を順に解説します。

  • View Transitions API とは何か、2025 年に急に注目される理由(ブラウザ対応率 85% 超)
  • Astro でページ遷移を有効にする 3 つの方法(2 行の最短ルートから高度なカスタムまで)
  • フェード、スライド、要素モーフィングなどのエフェクトの作り方
  • 実践:記事一覧から詳細ページへの滑らかな遷移
  • よくある落とし穴と対処法(筆者が実際に踏んだものです)

Astro サイトにアプリのような体験を足してみませんか? では始めましょう。

View Transitions API とは? なぜこんなに便利なのか

ブラウザ標準の「魔法」——ライブラリ不要

View Transitions API は、ブラウザが提供するネイティブ機能です。要するに「コンテンツを差し替えるよ」とブラウザに伝えると、旧ページと新ページのスナップショットを撮り、その間を滑らかにアニメーションしてくれます。

例えば、ブログ一覧に「Astro チュートリアル」という記事タイトルがあり、クリックして詳細へ移る場面を想像してください。従来は一覧が消える → 白画面 → 詳細が現れる、という流れです。View Transitions を使うと、ブラウザは一覧と詳細のタイトルを「同じ要素」と認識し、一覧の位置から詳細ページ上部へ滑らかに移動させつつ、他の部分はフェードで切り替えます。

最大の魅力は、アニメーションをブラウザが自動生成してくれる ことです。GSAP や Framer Motion のようなライブラリも、複雑な CSS アニメーションも不要です。

React/Vue なしで SPA のような体験を?

ページ遷移のアニメーションと聞くと、「React Router が必要」「Vue Router と transition コンポーネント」——そう思う人も多いでしょう。しかしこれらの方式には共通の弱点があります。重い のです。

従来の SPA フレームワークでページ遷移を実現するには次が必要です。

  • アプリ全体を単一ページ化し、ルーティングを JavaScript で制御する
  • バンドルサイズが増え、初回読み込みが遅くなる
  • SEO を別途ケアする(最近は改善されていますが)

Astro + View Transitions の組み合わせはずっとスマートです。

  • MPA(マルチページ)を維持:各ページが独立した HTML で、SEO に自然に強い
  • 必要なものだけ読み込み:現在のページに必要な JS と CSS だけ
  • ネイティブ API:オーバーヘッドが極小で、バンドルサイズもほぼ増えない
  • プログレッシブエンハンスメント:非対応ブラウザは通常の遷移に自動フォールバック

同じブログ構成で試したところ、React SPA 版は 300KB 超、Astro 版は 50KB 前後。View Transitions を足してもサイズはほぼ変わりませんでした。

85%+
ブラウザ対応率
2025 年時点の View Transitions API 対応率
50KB vs 300KB
バンドルサイズ比較
Astro 版は React SPA の約 1/6
2 行
設定コード
Layout の head に <ViewTransitions /> を追加

2025 年のブラウザ対応:安心して使える

朗報です。2025 年現在、View Transitions API のブラウザ対応率は 85% を超えています

具体的には次のとおりです。

  • Chrome 111+:同一ドキュメント内の状態切り替え(同ドキュメント遷移)
  • Chrome 126+:ドキュメント間の遷移(クロスドキュメント)—— Astro で使うのはこちら
  • Safari:対応済み
  • Edge:Chromium ベースで完全対応
  • Firefox 144+(2025 年 10 月リリース):Interop 2025 の重点項目で、Firefox も追随

React チームも 2025 年に View Transitions をコアに統合しました(react@canary で利用可能)。フロントエンド界の「当たり前」になりつつある API です。

残り 15% の非対応ブラウザが心配? 大丈夫です。Astro が自動でフォールバックします。非対応環境では通常のページ遷移になり、機能はそのまま。アニメーションがないだけです。プログレッシブエンハンスメント の良さがここにあります。

Astro で View Transitions を有効にする 3 つの方法

理論はここまで。実装に入りましょう。最も簡単な方法から説明します。読み終えたらすぐ試せるはずです。

方法 1:全体有効化(おすすめ、2 行で完了)

サイト全体にページ遷移を付けたいなら、これが最短です。Layout コンポーネント(多くは src/layouts/BaseLayout.astro または src/layouts/Layout.astro)の <head> に次の 2 行を追加します。


---

import { ViewTransitions } from 'astro:transitions';

---

<html>
  <head>
    <title>My Astro Site</title>
    <ViewTransitions />
  </head>
  <body>
    <slot />
  </body>
</html>

これだけです。npm run dev で開発サーバーを起動し、リンクをクリックしてみてください。ページ切り替えが滑らかなフェードに変わっているはずです。

初めて試したときは、ブラウザキャッシュのせいでは? と疑いました。何度かリロードして確認しても、本当にこれだけで動きます。

向いているサイト:ブログ、ドキュメント、ポートフォリオなど、サイト全体で遷移効果が欲しい場合。

方法 2:ページ単位で有効化

特定ページだけに効果を付けたい場合もあります。例えばトップと About だけ華やかに、管理画面はそのまま、といったケースです。そのページの <head> に追加します。


---

import { ClientRouter } from 'astro:transitions';

---

<html>
  <head>
    <title>About Page</title>
    <ClientRouter />
  </head>
  <body>
    <!-- ページ内容 -->
  </body>
</html>

補足:ClientRouter は新しい名称で、以前は ViewTransitions でした。Astro チームは「ビュー遷移だけでなくナビゲーションも横取りする」意味を明確にするため改名しました。旧名もまだ使え、エラーにはなりません。

向いているサイト:ページごとに挙動を分けたいハイブリッド構成。

方法 3:コードを触らずに試す

まず体感したいだけなら、Astro 公式デモが便利です。

👉 View Transitions Demo

一覧から詳細、画像ギャラリー、音楽プレーヤーなど、さまざまな遷移が試せます。好みの効果を見つけてから、自分のプロジェクトに持ち込むのがおすすめです。

ヒント:View Transitions 対応ブラウザ(Chrome 126+、Safari、最新 Firefox など)で開いてください。

有効化の確認ポイント 3 つ

コードを足したあと、本当に動いているか確認しましょう。

  1. 白画面のフラッシュが消える:リンククリック後、内容が滑らかに切り替わる
  2. ナビゲーションなど共通要素が再描画されない:ナビバーが消えて現れるのではなく、その場に留まる(後述の transition:persist も参照)
  3. コンソールにエラーがない:エラーが出る場合は Astro のバージョンや設定を疑う

初めてナビバーがちらつかないのを見たとき、目の錯覚かと思いました。View Transitions をオフにした版と比べて、初めて効いていると実感しました。

カスタム遷移アニメーション——ブランドに合わせた演出

デフォルトのフェードも十分シンプルですが、もっと個性的な動きが欲しいこともあります。ここでは 4 つのカスタム技法を、入門から応用まで紹介します。

技法 1:transition:animate でアニメーション種類を変える

Astro には 4 種類の組み込みアニメーションがあり、transition:animate ディレクティブで指定できます。記事本文を右からスライドさせたい例:

<article transition:animate="slide">
  <h1>記事タイトル</h1>
  <p>記事本文...</p>
</article>

4 種類は次のとおりです。

  1. fade(デフォルト):フェードイン・アウト。最も汎用的
  2. slide:右からスライドイン。記事詳細に向いている
  3. initial:ブラウザデフォルト。実質アニメーションなしに近い
  4. none:アニメーション完全オフ。遷移させたくない要素向け

よく使う組み合わせは、本文に slide、サイドバーに fade。レイヤー感が出ます。

時間も調整できます。fade()slide() 関数が用意されています。


---

import { fade, slide } from 'astro:transitions';

---

<article transition:animate={slide({ duration: '0.5s' })}>
  <!-- スライド 0.5 秒 -->
</article>

<aside transition:animate={fade({ duration: '0.2s' })}>
  <!-- フェード 0.2 秒 -->
</aside>

技法 2:transition:name で要素を「モーフィング」

View Transitions いちばん面白い機能です。transition:name で「この 2 ページの要素は同じものだ」とブラウザに伝え、変形アニメーションを任せられます。

定番は、記事一覧から詳細へのタイトル遷移です。

一覧ページ(index.astro):

<ul>
  <li>
    <a href="/posts/astro-guide">
      <h2 transition:name="post-title-astro-guide">Astro 完全ガイド</h2>
    </a>
  </li>
</ul>

詳細ページ(posts/astro-guide.astro):

<article>
  <h1 transition:name="post-title-astro-guide">Astro 完全ガイド</h1>
  <p>記事本文...</p>
</article>

両方のタイトルに同じ transition:name="post-title-astro-guide" を付けています。一覧項目をクリックすると、タイトルが一覧の位置から詳細上部へ移動し、フォントサイズや色も滑らかに変化します。

重要transition:name の値はページ内で一意にしてください。記事が複数ある場合は動的値が便利です。

{posts.map(post => (
  <h2 transition:name={`post-title-${post.slug}`}>{post.title}</h2>
))}

初めて使ったとき、タイトルが詳細ページ上部へ「飛んでいく」様子に、本当に魔法のような感覚がありました。

技法 3:transition:persist で要素の状態を保持

ページ遷移後も変えたくない要素があります。

  • 音楽プレーヤー(再生を止めたくない)
  • ナビゲーションバー(再描画を避けたい)
  • カートアイコン(数量表示を維持したい)

このときは transition:persist を使います。

<MusicPlayer client:load transition:persist />

他ページへ移動しても MusicPlayer は破棄・再生成されず、そのまま「移動」します。再生位置など内部状態も保持されます。

応用transition:persist-props との組み合わせ

デフォルトでは、遷移時に新しい props で再レンダリングされます。props も更新したくない場合(検索ボックスの入力内容を消したくないなど)は transition:persist-props を追加します。

<SearchBar
  client:load
  transition:persist
  transition:persist-props
/>

ドキュメントサイトで試したところ、検索欄に半分入力した状態でリンクを踏んでも文字が残り、体験がかなり良くなりました。

技法 4:ページ全体のアニメーションを制御

ページ全体のデフォルトアニメーションは <html> 要素で指定できます。

<html transition:animate="slide">
  <head>
    <ViewTransitions />
  </head>
  <body>
    <!-- すべて slide がデフォルト -->
  </body>
</html>

子要素で上書きも可能です。

<nav transition:animate="fade">
  <!-- ナビだけ fade -->
</nav>

<article>
  <!-- 記事は slide を継承 -->
</article>

大規模プロジェクトでも、階層的に制御しやすい方式です。

実践:ブログ全体の遷移体験を作る

ここまで理論と技法を見てきました。実際に、ブログの 一覧 → 記事詳細 の遷移を組み立てます。

シナリオ

ブログ構成は次の想定です。

  • 一覧:記事タイトル、概要、カバー画像
  • 詳細:タイトル、カバー、本文

目指す効果:

  1. タイトルクリックで、タイトルが詳細上部へモーフィング
  2. カバー画像もモーフィング
  3. その他はフェード
  4. ナビバーは状態を保持し、再描画しない

ステップ 1:Layout で View Transitions を有効化

src/layouts/BaseLayout.astro に ViewTransitions を追加します。


---

import { ViewTransitions } from 'astro:transitions';

interface Props {
  title: string;
}

const { title } = Astro.props;

---

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>{title}</title>
    <ViewTransitions />
  </head>
  <body>
    <nav transition:persist transition:name="main-nav">
      <a href="/">ホーム</a>
      <a href="/about">About</a>
    </nav>
    <main>
      <slot />
    </main>
  </body>
</html>

ナビには transition:persisttransition:name="main-nav" を付け、遷移時のちらつきを防ぎます。

ステップ 2:一覧ページ——タイトルとカバーに transition:name

src/pages/index.astro


---

import BaseLayout from '../layouts/BaseLayout.astro';

const posts = await Astro.glob('./posts/*.md');

---

<BaseLayout title="私のブログ">
  <h1>最新記事</h1>
  <div class="post-list">
    {posts.map(post => (
      <article class="post-card">
        <a href={post.url}>
          <img
            src={post.frontmatter.cover}
            alt={post.frontmatter.title}
            transition:name={`cover-${post.frontmatter.slug}`}
          />
          <h2 transition:name={`title-${post.frontmatter.slug}`}>
            {post.frontmatter.title}
          </h2>
          <p>{post.frontmatter.excerpt}</p>
        </a>
      </article>
    ))}
  </div>
</BaseLayout>

ポイント:

  • カバー:transition:name={'cover-${post.frontmatter.slug}'}
  • タイトル:transition:name={'title-${post.frontmatter.slug}'}
  • slug で記事ごとに一意な name を確保

ステップ 3:詳細ページ——同じ transition:name を使う

記事テンプレート(例:src/layouts/PostLayout.astro):


---

import BaseLayout from './BaseLayout.astro';

const { frontmatter } = Astro.props;

---

<BaseLayout title={frontmatter.title}>
  <article class="post-detail">
    <img
      src={frontmatter.cover}
      alt={frontmatter.title}
      transition:name={`cover-${frontmatter.slug}`}
      class="cover-image"
    />
    <h1 transition:name={`title-${frontmatter.slug}`}>
      {frontmatter.title}
    </h1>
    <div class="post-meta">
      <time>{frontmatter.date}</time>
      <span>{frontmatter.author}</span>
    </div>
    <div class="post-content" transition:animate="slide">
      <slot />
    </div>
  </article>
</BaseLayout>

カバーとタイトルの transition:name は一覧と一致させ、本文は transition:animate="slide" でスライドインさせます。

ステップ 4:CSS で遷移を滑らかに

Layout またはグローバル CSS に追加:

/* 遷移パフォーマンスの最適化 */
[transition:name] {
  will-change: transform;
}

/* 一覧と詳細でのカバー画像 */
.post-card img {
  width: 100%;
  height: 200px;
  object-fit: cover;
  border-radius: 8px;
}

.post-detail .cover-image {
  width: 100%;
  max-height: 400px;
  object-fit: cover;
  border-radius: 12px;
}

/* タイトル */
.post-card h2 {
  font-size: 1.5rem;
  color: #333;
}

.post-detail h1 {
  font-size: 2.5rem;
  color: #111;
  margin-top: 1rem;
}

will-change: transform は、この要素が変形アニメーションする旨をブラウザに伝え、事前最適化を促します。

ステップ 5:動作確認

開発サーバーを起動:

npm run dev

一覧を開き、記事タイトルをクリックすると次が見えるはずです。

  1. タイトルが一覧位置から詳細上部へ移動し、フォントサイズも変化
  2. カバー画像も移動しながら拡大
  3. ナビバーは動かず、ちらつかない
  4. 概要や公開日などは滑らかにフェードイン

初めてこの効果を見たとき、「これが欲しかった」と感じました。従来の硬い遷移と比べ、体験の差は大きいです。

任意:ローディング状態を追加

記事が重く読み込みに時間がかかる場合、Astro のフックでローディング表示も足せます。

<script>
  document.addEventListener('astro:before-preparation', () => {
    // ローディング表示
    document.body.classList.add('loading');
  });

  document.addEventListener('astro:page-load', () => {
    // ローディング非表示
    document.body.classList.remove('loading');
  });
</script>

<style>
  body.loading::after {
    content: '';
    position: fixed;
    top: 50%;
    left: 50%;
    width: 40px;
    height: 40px;
    border: 4px solid #f3f3f3;
    border-top: 4px solid #3498db;
    border-radius: 50%;
    animation: spin 1s linear infinite;
  }

  @keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
  }
</style>

コンテンツ読み込み中にスピナーを出せ、体験が一段整います。

応用テクニックとよくある問題

基礎と実践のあと、応用のコツと、筆者が踏んだ落とし穴を共有します。

応用 1:「アニメーションを減らす」設定を尊重する

前庭障害などで酔いやすいユーザー、単にアニメーションが苦手なユーザーは、OS で「アニメーションを減らす」を有効にしています。開発者として、この設定には配慮すべきです。

Astro とブラウザが自動で処理してくれますが、CSS で明示的に制御することもできます。

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Astro コンポーネント側で特定アニメーションだけオフにする例:

<div transition:animate={
  typeof window !== 'undefined' &&
  window.matchMedia('(prefers-reduced-motion: reduce)').matches
    ? 'none'
    : 'slide'
}>
  コンテンツ
</div>

地味ですが、一部のユーザーにとっては重要な配慮です。

応用 2:スクリプトのライフサイクルを扱う

従来の MPA では、ページ遷移のたびにスクリプトが再実行されます。View Transitions 有効時は「擬似 SPA」になり、挙動が変わります。

Astro が提供するライフサイクルイベント:

// ページ読み込み完了(初回とナビゲーション後)
document.addEventListener('astro:page-load', () => {
  console.log('ページ内容が更新されました');
  // UI コンポーネントの再初期化、イベント再バインドなど
});

// ナビゲーション開始直前
document.addEventListener('astro:before-preparation', () => {
  console.log('新しいページへナビゲートします');
  // タイマー解除、進行中リクエストのキャンセルなど
});

// ナビゲーションキャンセル後(戻るボタンなど)
document.addEventListener('astro:after-swap', () => {
  console.log('DOM は更新済みだがアニメーションは未完了');
});

よくある落とし穴:イベントリスナーを張ったまま放置すると、ナビゲーションを繰り返すうちにメモリリークやカクつきの原因になります。astro:before-preparation で必ず解除しましょう。

過去のプロジェクトでは、スクロールリスナーの解除を忘れ、数回遷移するとページが重くなりました。クリーンアップを足して解消しました。

応用 3:パフォーマンスを最適化する

View Transitions 自体は軽量ですが、対象要素が多すぎたり複雑すぎるとカクつくことがあります。

  1. 同時に遷移させる要素を絞る:すべてに transition:name を付けない。キー要素だけ
  2. will-change: transform を使う:ブラウザに事前最適化を促す
  3. アニメーション中に reflow を起こさない:width、height、padding などレイアウト属性は避ける
  4. 実機でテストする:開発 PC が快適でも、ユーザーの端末は違う
/* 良い例 */
.animated-element {
  will-change: transform, opacity;
  transform: translateX(0);
}

/* 悪い例 */
.animated-element {
  width: 100px; /* width 変更は reflow を誘発し、性能が落ちる */
}

よくある問題 1:アニメーションが効かない

症状transition:name を付けたのに、硬い遷移のまま。

原因と対処

  1. transition:name が重複:同一ページ内で name が一意か確認
  2. ページ間で name が不一致:一覧と詳細で同じ name か確認
  3. ブラウザ非対応:DevTools コンソールでエラー確認
  4. Astro が古い:Astro 3.0 以上が必要(View Transitions は 3.0 で導入)
# Astro バージョン確認
npx astro --version

# Astro を更新
npm install astro@latest

よくある問題 2:要素がちらつく・位置が跳ねる

症状:遷移中に一瞬光ったり、位置がずれる。

原因と対処

  1. CSS がページ間で不一致:display、position など基本スタイルを揃える
  2. 画像の読み込み未完了loading="eager" や固定 height を検討
  3. transition:persist 不足:ナビやプレーヤーなど、保持したい要素に付ける
<!-- 画像のちらつき対策 -->
<img
  src={cover}
  loading="eager"
  style="height: 200px"
  transition:name="cover"
/>

よくある問題 3:戻るボタンのアニメーション方向がおかしい

症状:進むときは自然だが、戻るときも同じ方向にスライドする。

対処:Astro が進む/戻るの方向を処理しますが、カスタムアニメーションでは手動調整が必要な場合があります。

document.addEventListener('astro:before-preparation', (event) => {
  const isBack = event.direction === 'back';
  if (isBack) {
    document.documentElement.classList.add('reverse-animation');
  }
});
.reverse-animation [transition:animate="slide"] {
  animation-direction: reverse;
}

よくある問題 4:サードパーティスクリプトと競合

症状:View Transitions 導入後、Google Analytics や広告スクリプトが動かない。

原因:これらは通常、ページ読み込み時に一度だけ実行されます。View Transitions はナビゲーションを横取りするため、ページが変わってもスクリプト側が気づきません。

対処astro:page-load で再実行します。

document.addEventListener('astro:page-load', () => {
  // Google Analytics
  if (typeof gtag !== 'undefined') {
    gtag('config', 'GA_MEASUREMENT_ID', {
      page_path: window.location.pathname,
    });
  }

  // Facebook Pixel
  if (typeof fbq !== 'undefined') {
    fbq('track', 'PageView');
  }
});

筆者も最初、View Transitions 導入後に GA の数値がおかしくなり、手動トリガーが必要だと気づきました。

互換性とプログレッシブエンハンスメント

View Transitions の対応率は 85% 超と高いですが、未対応ブラウザは残ります。Astro は自動フォールバックするため、非対応環境でも通常のページ遷移として問題なく動きます。

手動で対応可否を確認する例:

if (document.startViewTransition) {
  console.log('ブラウザは View Transitions に対応しています');
} else {
  console.log('非対応のため、通常の遷移にフォールバック');
}

モダンブラウザでは滑らかな体験、旧環境でも壊れない——プログレッシブエンハンスメントの典型です。

まとめ

ここまでの要点を整理します。

View Transitions API + Astro = いちばん手軽なページ遷移の解決策 です。React も Vue もサードパーティライブラリも不要。Layout の <head> に 2 行足すだけで、Astro サイトにアプリのような滑らかさが加わります。

フェードからスライド、要素モーフィング、状態保持まで、硬い MPA をモダンな Web アプリのような体験に変えられます。しかもネイティブ API ベースでオーバーヘッドは小さく、旧ブラウザにも自動フォールバックします。

今すぐ試すなら、次の順がおすすめです。

  1. まず最短ルート:Layout に <ViewTransitions /> を入れ、デフォルト効果を確認
  2. 感動ポイントを見つける:ナビがちらつかない、タイトルがモーフィングする——など
  3. 必要に応じて調整transition:animatetransition:name でサイトのトーンに合わせる
  4. 実環境で検証:ブラウザとデバイスを変えて確認

新規プロジェクトでは、最初から View Transitions を入れることが多いです。シンプルなのに効果が大きい。良い UX は必ずしも複雑なコードではなく、適切なツール選びから生まれます。

実装で詰まったら:

View Transitions で面白い効果ができたら、ぜひコメント欄でサイト URL をシェアしてください。みなさんのクリエイティブも見てみたいです。

さあ、Astro プロジェクトを開いて、サイトを滑らかにしていきましょう。

Astro View Transitions 設定の完全フロー

2 行のコードで Web サイトにアプリのような滑らかな体験を。基本設定から高度なカスタムまで、実践チュートリアル付き

⏱️ 目安時間: 15 分

  1. 1

    ステップ1: View Transitions API とブラウザ対応を理解する

    View Transitions API とは:
    • ブラウザが提供するネイティブ機能
    • 「コンテンツを差し替える」と伝えると、旧ページと新ページのスナップショットを撮影
    • その間を滑らかにアニメーション
    • アニメーションはブラウザが自動生成
    • GSAP や Framer Motion などのライブラリは不要

    2025 年のブラウザ対応率 85% 超:
    • Chrome 111+:同一ドキュメント内の状態切り替え
    • Chrome 126+:ドキュメント間遷移(Astro で使用)
    • Safari:対応済み
    • Edge:Chromium ベースで完全対応
    • Firefox 144+:Interop 2025 の重点項目として対応

    React チームも 2025 年に View Transitions をコアに統合(react@canary 対応)。フロントエンドの標準 API になりつつある。

    互換性:
    • Astro が自動フォールバック
    • 非対応ブラウザでは通常のページ遷移
    • 機能はそのまま、アニメーションだけ省略
    • プログレッシブエンハンスメント
  2. 2

    ステップ2: Astro + View Transitions 組み合わせの強み

    React/Vue なしで SPA 体験を実現する理由:

    従来 SPA の課題:
    • アプリ全体を単一ページ化
    • ルーティングを JavaScript で制御
    • バンドルサイズ増、初回読み込み遅延
    • SEO を別途ケア

    Astro + View Transitions の強み:
    • MPA を維持。各ページが独立 HTML で SEO に強い
    • 必要な JS/CSS だけ読み込み
    • ネイティブ API でオーバーヘッド極小、バンドルサイズほぼ不変
    • 非対応ブラウザは通常遷移に自動フォールバック

    性能比較:
    • 同じブログ構成で検証
    • React SPA 版:300KB 超
    • Astro 版:50KB 前後
    • View Transitions 追加後もサイズはほぼ変わらず
  3. 3

    ステップ3: 3 つの有効化方法:最短から高度なカスタムまで

    方法 1:最短ルート
    • Layout の <head> に <ViewTransitions /> を追加
    • 2 行で完了
    • ページ切り替えが滑らかな遷移に
    • React/Vue/追加 JS ライブラリ不要

    方法 2:カスタム遷移
    • transition:animate で種類を指定
    - fade:フェード
    - slide:スライド
    - none:アニメーションなし
    • transition:name で要素に名前を付与
    • 一覧と詳細のタイトルを「同じ要素」と認識させ、位置を滑らかに移動

    方法 3:高度な使い方
    • 要素モーフィング:一覧サムネから詳細の大画像へ拡大
    • 状態保持:スクロール位置やフォーム入力を維持
    • アニメーション時間とイージングのカスタム
  4. 4

    ステップ4: 実践:記事一覧から詳細ページへの滑らかな遷移

    実践シナリオ:

    一覧に「Astro チュートリアル」があり、クリックで詳細へ。

    従来:
    • 一覧消失 → 白画面 → 詳細表示

    View Transitions 後:
    • タイトルを同一要素と認識
    • 一覧位置から詳細上部へ滑らかに移動
    • 他コンテンツはフェード

    設定手順:
    1. Layout の head に <ViewTransitions /> を追加
    2. 記事タイトルに transition:name を付与(例:transition:name="article-title")
    3. 任意:transition:animate="slide" でスライド効果
    4. ブラウザとデバイスで動作確認

    期待できる効果:
    • ナビバーがちらつかない
    • タイトルのモーフィング
    • 画像の滑らかな遷移
    • 硬い再読み込みからアプリのような体験へ
  5. 5

    ステップ5: よくある問題とベストプラクティス

    よくある問題:1) アニメーションが効かない(ブラウザ対応とコンソールエラーを確認)、2) モーフィングが不自然(transition:name の値を一致させ、要素構造を揃える)、3) 性能問題(ネイティブ API でオーバーヘッドは小さいが、要素が多すぎると重くなる。キー要素だけに限定)。ベストプラクティス:まず Layout に <ViewTransitions /> を入れてデフォルトを確認、感動ポイント(ナビ非ちらつき、タイトルモーフィングなど)を見つけ、transition:animate と transition:name で調整、複数ブラウザ・デバイスで検証。互換性:対応率 85% 超だが未対応もあり、Astro が自動フォールバックするため機能は維持される。

FAQ

View Transitions API とは? なぜこんなに便利なのか?
View Transitions API はブラウザのネイティブ機能です。「コンテンツを差し替える」と伝えると、旧ページと新ページのスナップショットを撮り、その間を滑らかにアニメーションします。

アニメーションはブラウザが自動生成するため、複雑な CSS や GSAP、Framer Motion などのライブラリは不要です。

例:一覧に「Astro チュートリアル」があり、詳細へ移る場合。
• 従来:一覧消失 → 白画面 → 詳細表示
• View Transitions 後:タイトルを同一要素と認識し、一覧位置から詳細上部へ移動。他はフェード
2025 年のブラウザ対応は? 安心して使える?
2025 年時点で対応率 85% 超:
• Chrome 111+:同一ドキュメント内遷移
• Chrome 126+:ドキュメント間遷移(Astro で使用)
• Safari:対応済み
• Edge:Chromium ベースで完全対応
• Firefox 144+:Interop 2025 の重点項目として対応

React も 2025 年に View Transitions をコア統合(react@canary)。フロントエンドの標準になりつつあります。

残り 15% の非対応ブラウザも、Astro が自動フォールバック。通常のページ遷移になり、機能はそのまま。アニメーションがないだけです。
React/Vue なしで SPA のような体験を実現できる理由は?
従来 SPA でページ遷移を実現するには:
• アプリ全体を単一ページ化し、JavaScript でルーティング
• バンドルサイズ増、初回読み込み遅延
• SEO を別途ケア

Astro + View Transitions なら:
• MPA を維持。各ページが独立 HTML で SEO に強い
• 必要な JS/CSS だけ読み込み
• ネイティブ API でオーバーヘッド極小
• 非対応ブラウザは通常遷移に自動フォールバック

同じブログで試すと、React SPA は 300KB 超、Astro は 50KB 前後。View Transitions 追加後もサイズはほぼ不変。
Astro で View Transitions を有効にする方法は? いくつある?
方法 1(最短):
• Layout の <head> に <ViewTransitions /> を追加
• 2 行で滑らかな遷移が実現
• React/Vue/追加ライブラリ不要

方法 2(カスタム):
• transition:animate(fade / slide / none)
• transition:name で要素を命名し、一覧と詳細の同一要素を認識させる

方法 3(高度):
• 要素モーフィング(サムネから詳細画像へ拡大)
• 状態保持(スクロール、フォーム入力など)
• アニメーション時間とイージングの調整
記事一覧から詳細ページへの滑らかな遷移はどう実装する?
例:一覧の「Astro チュートリアル」をクリックして詳細へ。
• 従来:一覧消失 → 白画面 → 詳細
• View Transitions:タイトルを同一要素と認識し、位置を滑らかに移動。他はフェード

手順:
1) Layout の head に <ViewTransitions />
2) タイトルに transition:name(例:transition:name="article-title")
3) 任意:transition:animate="slide"
4) ブラウザ・デバイスで検証

効果:ナビ非ちらつき、タイトルモーフィング、画像の滑らかな遷移。硬い再読み込みからアプリ体験へ。
View Transitions 利用時のよくある問題とベストプラクティスは?
よくある問題:
1) アニメーションが効かない
• ブラウザ対応を確認
• コンソールエラーを確認

2) モーフィングが不自然
• transition:name の値を一致させる
• 要素構造を揃える

3) 性能問題
• ネイティブ API でオーバーヘッドは小さい
• 要素が多すぎると重くなる。キー要素だけに限定

ベストプラクティス:
• まず Layout に <ViewTransitions /> でデフォルト確認
• ナビ非ちらつきやタイトルモーフィングなど、効いている点を把握
• transition:animate / transition:name で調整
• 複数ブラウザ・デバイスで検証

互換性:対応率 85% 超だが未対応もあり。Astro が自動フォールバック。手動確認は if (document.startViewTransition) で可能。

7分で読めます · 公開日: 2025年12月2日 · 更新日: 2026年6月8日

関連記事

コメント

GitHubアカウントでログインしてコメントできます