Documentation CSS

この記事で学べること

  • scroll-timeline-nameプロパティの概念と目的
  • タイムライン名の命名規則と設定方法
  • スクロールコンテナとアニメーションの関連付け
  • 複数のタイムラインを活用した高度なアニメーション
  • ブラウザ対応状況とフォールバック実装

概要

scroll-timeline-nameプロパティは、CSSのスクロール駆動アニメーション(Scroll-driven Animations)機能の中核を担うプロパティです。このプロパティを使用することで、スクロールコンテナに対して識別可能な名前を付け、その名前を使ってアニメーションとスクロール位置を関連付けることができます。

スクロール駆動アニメーションとは、従来の時間ベースのアニメーションとは異なり、ユーザーのスクロール位置に基づいてアニメーションの進行度を決定する仕組みです。scroll-timeline-nameでタイムラインに名前を付けることで、離れた要素のアニメーションを特定のスクロールコンテナに紐付けることができます。

scroll-timeline-nameプロパティの基本構文

scroll-timeline-nameプロパティは以下の構文で使用します。

/* タイムライン名を指定 */
scroll-timeline-name: --main-scroll;

/* 複数のタイムライン名を指定 */
scroll-timeline-name: --timeline-1, --timeline-2;

/* タイムラインを無効化 */
scroll-timeline-name: none;

値の説明

説明
noneタイムラインを定義しない(デフォルト値)
--カスタム名タイムラインに付ける名前。必ずダブルハイフン(—)で始める必要がある

命名規則

タイムライン名には以下のルールがあります。

/* OK - ダブルハイフンで始まる */
scroll-timeline-name: --my-scroll;
scroll-timeline-name: --page-timeline;
scroll-timeline-name: --sidebar-progress;

/* NG - ダブルハイフンで始まっていない */
scroll-timeline-name: my-scroll;      /* 無効 */
scroll-timeline-name: page-timeline;  /* 無効 */

この命名規則はCSS変数(カスタムプロパティ)と同じで、CSSの標準プロパティとの競合を防ぎ、カスタム定義であることを明示します。

使用例

基本的な使用例:スクロールに連動したプログレスバー

ページの上部に固定されたプログレスバーが、スクロール量に応じて伸びていく基本的な例です。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>scroll-timeline-nameの基本例</title>
<style>
/* スクロールコンテナにタイムライン名を設定 */
.scroll-container {
  /* タイムラインに「--main-scroll」という名前を付ける */
  scroll-timeline-name: --main-scroll;
  height: 100vh;
  overflow-y: scroll;
}

/* プログレスバーのアニメーション定義 */
@keyframes grow-progress {
  from {
    /* アニメーション開始時:幅0% */
    transform: scaleX(0);
  }
  to {
    /* アニメーション終了時:幅100% */
    transform: scaleX(1);
  }
}

/* プログレスバーのスタイル */
.progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background: linear-gradient(90deg, #3b82f6, #8b5cf6);
  transform-origin: left;

  /* アニメーションを設定 */
  animation: grow-progress linear;

  /* --main-scrollタイムラインに紐付け */
  animation-timeline: --main-scroll;
}

/* コンテンツエリア */
.content {
  height: 300vh;
  padding: 20px;
  background: linear-gradient(180deg, #f0f9ff, #e0f2fe);
}
</style>
</head>
<body>
<div class="scroll-container">
  <div class="progress-bar"></div>
  <div class="content">
    <h1>スクロールしてください</h1>
    <p>ページをスクロールすると、上部のプログレスバーが進行します。</p>
  </div>
</div>
</body>
</html>

この例のポイントは以下の通りです。

  1. .scroll-containerscroll-timeline-name: --main-scrollを設定してタイムラインに名前を付ける
  2. .progress-baranimation-timeline: --main-scrollでそのタイムラインを参照
  3. スクロール位置に応じて@keyframesのアニメーションが進行する

複数のタイムラインを使用した例

ページ内に複数のスクロール領域があり、それぞれ独立したアニメーションを持つ例です。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>複数のスクロールタイムライン</title>
<style>
.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  padding: 20px;
  height: 100vh;
}

/* 左側のスクロールエリア */
.left-panel {
  /* 左パネル専用のタイムライン名 */
  scroll-timeline-name: --left-scroll;
  overflow-y: scroll;
  border: 2px solid #3b82f6;
  border-radius: 8px;
}

/* 右側のスクロールエリア */
.right-panel {
  /* 右パネル専用のタイムライン名 */
  scroll-timeline-name: --right-scroll;
  overflow-y: scroll;
  border: 2px solid #8b5cf6;
  border-radius: 8px;
}

/* パネル内のコンテンツ */
.panel-content {
  height: 200vh;
  padding: 20px;
}

/* 左パネル用インジケーター */
.left-indicator {
  position: fixed;
  top: 50%;
  left: 20px;
  width: 10px;
  height: 100px;
  background: #3b82f6;
  border-radius: 5px;
  animation: slide-down linear;
  /* 左パネルのタイムラインに紐付け */
  animation-timeline: --left-scroll;
}

/* 右パネル用インジケーター */
.right-indicator {
  position: fixed;
  top: 50%;
  right: 20px;
  width: 10px;
  height: 100px;
  background: #8b5cf6;
  border-radius: 5px;
  animation: slide-down linear;
  /* 右パネルのタイムラインに紐付け */
  animation-timeline: --right-scroll;
}

@keyframes slide-down {
  from {
    transform: translateY(-100px);
    opacity: 0.3;
  }
  to {
    transform: translateY(100px);
    opacity: 1;
  }
}
</style>
</head>
<body>
<div class="container">
  <div class="left-panel">
    <div class="panel-content">
      <h2>左パネル</h2>
      <p>このエリアをスクロールすると左のインジケーターが動きます。</p>
    </div>
  </div>
  <div class="right-panel">
    <div class="panel-content">
      <h2>右パネル</h2>
      <p>このエリアをスクロールすると右のインジケーターが動きます。</p>
    </div>
  </div>
</div>
<div class="left-indicator"></div>
<div class="right-indicator"></div>
</body>
</html>

この例では、2つの独立したスクロールエリアがそれぞれ別のタイムライン名(--left-scroll--right-scroll)を持ち、対応するインジケーターが独立して動作します。

scroll-timelineショートハンドとの比較

scroll-timeline-namescroll-timeline-axisと組み合わせて使用することが多いため、ショートハンドプロパティscroll-timelineも用意されています。

/* 個別に指定する場合 */
.scroll-container {
  scroll-timeline-name: --my-timeline;
  scroll-timeline-axis: block;
}

/* ショートハンドで指定する場合 */
.scroll-container {
  /* 名前と軸を一度に指定 */
  scroll-timeline: --my-timeline block;
}

/* 軸を省略した場合(デフォルトはblock) */
.scroll-container {
  scroll-timeline: --my-timeline;
}

実践的な例:セクションごとのフェードイン効果

ページをスクロールすると、各セクションがフェードインしながら表示される例です。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>セクションフェードイン効果</title>
<style>
/* ルート要素にタイムラインを設定 */
html {
  scroll-timeline-name: --page-scroll;
}

body {
  margin: 0;
  font-family: sans-serif;
}

/* セクションの共通スタイル */
.section {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 48px;
  font-weight: bold;
  color: white;
}

.section:nth-child(1) { background: #1e3a8a; }
.section:nth-child(2) { background: #7c3aed; }
.section:nth-child(3) { background: #dc2626; }
.section:nth-child(4) { background: #059669; }

/* フェードインアニメーション */
@keyframes fade-in-section {
  0%, 15% {
    opacity: 0;
    transform: translateY(50px);
  }
  25%, 75% {
    opacity: 1;
    transform: translateY(0);
  }
  85%, 100% {
    opacity: 0;
    transform: translateY(-50px);
  }
}

/* 各セクションのコンテンツにアニメーションを適用 */
.section-content {
  animation: fade-in-section linear;
  animation-timeline: --page-scroll;
}

/* 各セクションのアニメーション範囲を調整 */
.section:nth-child(1) .section-content {
  animation-range: 0% 25%;
}

.section:nth-child(2) .section-content {
  animation-range: 25% 50%;
}

.section:nth-child(3) .section-content {
  animation-range: 50% 75%;
}

.section:nth-child(4) .section-content {
  animation-range: 75% 100%;
}
</style>
</head>
<body>
<div class="section">
  <div class="section-content">Section 1</div>
</div>
<div class="section">
  <div class="section-content">Section 2</div>
</div>
<div class="section">
  <div class="section-content">Section 3</div>
</div>
<div class="section">
  <div class="section-content">Section 4</div>
</div>
</body>
</html>

この例では、animation-rangeプロパティを使用して各セクションのアニメーションが発火するスクロール位置を制御しています。

scroll-timeline-nameと関連プロパティ

scroll-timeline-nameは、スクロール駆動アニメーションの一連のプロパティと組み合わせて使用します。

プロパティ説明
scroll-timeline-nameスクロールタイムラインに名前を付ける
scroll-timeline-axisタイムラインの軸方向を指定(block、inline、x、y)
scroll-timeline上記2つのショートハンドプロパティ
animation-timelineアニメーションに適用するタイムラインを指定
animation-rangeアニメーションが発火するスクロール範囲を指定

タイムラインの参照スコープ

scroll-timeline-nameで定義されたタイムラインは、その要素の子孫要素から参照できます。また、同じ名前のタイムラインが複数定義されている場合、最も近い祖先のタイムラインが使用されます。

/* 親コンテナにタイムラインを定義 */
.parent {
  scroll-timeline-name: --shared-timeline;
}

/* 子要素からタイムラインを参照 */
.child {
  animation: my-animation linear;
  animation-timeline: --shared-timeline;
}

注意点

ブラウザ対応状況

scroll-timeline-nameプロパティは、CSS Scroll-driven Animations仕様の一部であり、比較的新しい機能です。

  • Chrome/Edge: バージョン115以降でサポート
  • Firefox: バージョン110以降でフラグ付きでサポート(layout.css.scroll-driven-animations.enabled
  • Safari: 2024年時点では未サポート

本番環境で使用する場合は、@supportsを使用してフォールバックを実装することを強く推奨します。

/* フォールバック:スクロール駆動アニメーション非対応ブラウザ向け */
.progress-bar {
  /* デフォルトで表示しない、または静的なスタイルを適用 */
  transform: scaleX(0);
}

/* スクロール駆動アニメーション対応ブラウザ向け */
@supports (animation-timeline: scroll()) {
  .progress-bar {
    animation: grow-progress linear;
    animation-timeline: --main-scroll;
  }
}

パフォーマンスに関する考慮事項

スクロール駆動アニメーションを効率的に動作させるためのベストプラクティスです。

/* 推奨:GPUで処理されるプロパティを使用 */
@keyframes good-animation {
  from {
    transform: translateX(0);
    opacity: 0;
  }
  to {
    transform: translateX(100px);
    opacity: 1;
  }
}

/* 非推奨:レイアウトに影響するプロパティを避ける */
@keyframes bad-animation {
  from {
    width: 0;
    margin-left: 0;
  }
  to {
    width: 100%;
    margin-left: 50px;
  }
}

以下のプロパティは、GPUでの高速処理が可能なため推奨されます。

  • transform(translate、scale、rotate)
  • opacity
  • filter

名前の衝突を避ける

大規模なプロジェクトでは、タイムライン名の衝突を避けるために、命名規則を統一することを推奨します。

/* コンポーネント名をプレフィックスとして使用 */
.header {
  scroll-timeline-name: --header-scroll;
}

.sidebar {
  scroll-timeline-name: --sidebar-scroll;
}

.main-content {
  scroll-timeline-name: --main-content-scroll;
}

まとめ

scroll-timeline-nameプロパティは、スクロール駆動アニメーションの中心的な役割を担う重要なプロパティです。主なポイントは以下の通りです。

ポイントの振り返り

項目内容
目的スクロールタイムラインに識別可能な名前を付ける
命名規則必ずダブルハイフン(—)で始める
参照方法animation-timelineプロパティで名前を指定
ショートハンドscroll-timelineで名前と軸を同時に指定可能

スクロール駆動アニメーションを活用することで、ユーザーのスクロール操作に応じた直感的でインタラクティブな体験を提供できます。scroll-timeline-nameを使って、スクロールコンテナとアニメーションを明確に関連付け、魅力的なWebページを作成しましょう。

参考文献

円