CSS疑似要素 ::view-transition-old の詳細解説


::view-transition-old は、遷移前の古いビューの状態を表す静的なスクリーンショットを表します。これは、::view-transition-image-pair の子要素としてのみ存在し、自身の子要素を持つことはできません。

ビュー遷移 のプロセスは以下の通りです。

  1. ブラウザは、古いビュー新しいビュー のスクリーンショットを撮ります。
  2. DOM が更新されますが、レンダリングは抑制されます。
  3. ブラウザは、古いビュー から 新しいビュー へのアニメーションをレンダリングします。
  4. アニメーションが完了すると、新しいビューが表示されます。

::view-transition-old は、このアニメーションプロセスの中で、以下の役割を果たします。

  • アニメーションの滑らかさを向上させるために使用できます。
  • 新しいビュー との比較を可能にします。
  • 古いビュー の視覚的な表現を提供します。

例: ::view-transition-old を使用したクロスフェードアニメーション

/* 古いビューの状態 */
::view-transition-old {
  opacity: 1;
}

/* 新しいビューの状態 */
::view-transition-new {
  opacity: 0;
}

/* アニメーション */
@keyframes view-transition {
  from { opacity: 1; }
  to { opacity: 0; }
}

.element {
  view-transition-name: view-transition;
  transition: opacity 0.5s ease;
}

この例では、.element クラスを持つ要素が 5秒 かけで 透明度1 から 0 に変化させます。::view-transition-old は、アニメーションの開始時に古いビューの状態を完全に表示し、アニメーションの終了時に新しいビューの状態を完全に表示するために使用されます。

ブラウザサポート

::view-transition-old は、比較的新しい CSS 機能であり、すべてのブラウザでサポートされているわけではありません。以下の表は、主要なブラウザにおけるサポート状況を示しています。

ブラウザサポート
Chrome76以降
Edge80以降
Firefox72以降
Safari13以降

::view-transition-old を使用する場合は、ブラウザ互換性を考慮する必要があります。古いブラウザでは、この機能がサポートされていない可能性があるため、代替手段を用意する必要があります。



例 1: フェードイン・フェードアウト

この例では、2つのページ間の遷移時にフェードイン・フェードアウトアニメーションを作成します。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>フェードイン・フェードアウト</title>
  <style>
    /* 古いビューの状態 */
    ::view-transition-old {
      opacity: 1;
    }

    /* 新しいビューの状態 */
    ::view-transition-new {
      opacity: 0;
    }

    /* アニメーション */
    @keyframes view-transition {
      from { opacity: 0; }
      to { opacity: 1; }
    }

    .page {
      view-transition-name: view-transition;
      transition: opacity 0.5s ease;
    }
  </style>
</head>
<body>
  <div class="page" id="page1">
    <h1>ページ 1</h1>
    <p>これは最初のページです。</p>
  </div>

  <div class="page" id="page2" style="display: none;">
    <h1>ページ 2</h1>
    <p>これは2番目のページです。</p>
  </div>

  <script>
    const page1 = document.getElementById('page1');
    const page2 = document.getElementById('page2');

    page1.addEventListener('click', () => {
      page1.style.display = 'none';
      page2.style.display = 'block';
    });
  </script>
</body>
</html>

このコードを実行すると、最初に "ページ 1" が表示されます。"ページ 1" をクリックすると、"ページ 2" がフェードインし、"ページ 1" がフェードアウトします。

例 2: スライドイン・スライドアウト

この例では、2つのページ間の遷移時にスライドイン・スライドアウトアニメーションを作成します。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>スライドイン・スライドアウト</title>
  <style>
    /* 古いビューの状態 */
    ::view-transition-old {
      transform: translateX(100%);
    }

    /* 新しいビューの状態 */
    ::view-transition-new {
      transform: translateX(0);
    }

    /* アニメーション */
    @keyframes view-transition {
      from { transform: translateX(100%); }
      to { transform: translateX(0); }
    }

    .page {
      view-transition-name: view-transition;
      transition: transform 0.5s ease;
      width: 100%;
      overflow: hidden;
    }
  </style>
</head>
<body>
  <div class="page" id="page1">
    <h1>ページ 1</h1>
    <p>これは最初のページです。</p>
  </div>

  <div class="page" id="page2" style="display: none;">
    <h1>ページ 2</h1>
    <p>これは2番目のページです。</p>
  </div>

  <script>
    const page1 = document.getElementById('page1');
    const page2 = document.getElementById('page2');

    page1.addEventListener('click', () => {
      page1.style.display = 'none';
      page2.style.display = 'block';
    });
  </script>
</body>
</html>

このコードを実行すると、最初に "ページ 1" が表示されます。"ページ 1" をクリックすると、"ページ 2" が右側からスライドインし、"ページ 1" が左側にスライドアウトします。

例 3: ズームイン・ズームアウト

この例では、2つのページ間の遷移時にズームイン・ズームアウトアニメーションを作成します。

<!DOCTYPE html>
<html lang="ja">


代替方法としては、以下の3つが挙げられます。

CSS アニメーション

CSS アニメーションを使用して、独自のビュー遷移を作成することができます。これは、::view-transition-oldよりも柔軟性があり、より複雑なアニメーションを作成することができます。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSSアニメーション</title>
  <style>
    .page {
      position: absolute;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
    }

    .page.active {
      z-index: 1;
    }

    .page.inactive {
      z-index: 0;
    }

    .page.enter {
      animation: enter 0.5s ease-in-out forwards;
    }

    .page.leave {
      animation: leave 0.5s ease-in-out forwards;
    }

    @keyframes enter {
      from { opacity: 0; transform: scale(0.5); }
      to { opacity: 1; transform: scale(1); }
    }

    @keyframes leave {
      from { opacity: 1; transform: scale(1); }
      to { opacity: 0; transform: scale(0.5); }
    }
  </style>
</head>
<body>
  <div class="page" id="page1" class="active">
    <h1>ページ 1</h1>
    <p>これは最初のページです。</p>
  </div>

  <div class="page" id="page2" class="inactive">
    <h1>ページ 2</h1>
    <p>これは2番目のページです。</p>
  </div>

  <script>
    const page1 = document.getElementById('page1');
    const page2 = document.getElementById('page2');

    page1.addEventListener('click', () => {
      page1.classList.remove('active');
      page1.classList.add('leave');

      page2.classList.add('active');
      page2.classList.add('enter');
    });
  </script>
</body>
</html>

JavaScript ライブラリ

GreenSockVelocity.js などの JavaScript ライブラリを使用して、ビュー遷移を作成することができます。これらのライブラリは、CSS アニメーションよりも多くの機能を提供しており、複雑なアニメーションを作成するのに役立ちます。

カスタム要素

Web Components を使用して、独自のビュー遷移要素を作成することができます。これは、より高度なカスタマイズと再利用性を提供します。

どの代替方法を選択するかは、要件とスキルレベルによって異なります。

  • 古いブラウザでの互換性が重要の場合は、JavaScript ライブラリまたはカスタム要素がおすすめです。
  • より複雑なアニメーションが必要な場合は、JavaScript ライブラリまたはカスタム要素がおすすめです。
  • シンプルで柔軟なアニメーションが必要な場合は、CSS アニメーションがおすすめです。

上記以外にも、::view-transition-old の代替となる方法はいくつかあります。例えば、以下のような方法があります。

  • 古いビューを非表示にしてから新しいビューを表示する
  • 古いビューと新しいビューを直接重ねて表示する
  • CSS プロパティの transition を使用する

これらの方法は、::view-transition-old ほど洗練されていませんが、シンプルなアニメーションを作成する場合には有効です。