animation-timeline / Scroll-driven Animations
スクロール位置や要素のビューポート進入率を「タイムライン」として CSS アニメーションに繋ぐ仕様。 JS なし / GSAP なしでパララックス・進捗バー・リビールが書ける。
これは何か
従来の animation は時間(秒)でアニメーションを進める。
Scroll-driven Animations は「スクロール量 / 要素の見え方」でアニメを進めるための CSS 拡張。
- JS 不要で実装可能
- WAAPI からも使える(より動的な制御)
- GPU に乗りやすく滑らか
- スクロールイベントを直接拾うより桁違いに軽い
2026 年時点のサポート
- Chrome / Edge / Opera: 完全対応(115+)
- Safari: 段階的対応中(基本機能は使える)
- Firefox: フラグ付きで実装中(標準対応はもう少し)
- 非対応環境向けにpolyfill あり(@oddbird/css-anchor-positioning じゃなくて scroll-timeline 用 polyfill)
コア概念
タイムライン
「アニメーションの進行度(0〜1)」をどこから取るかを決める。
- document timeline(既定)— 時間ベース
- scroll timeline — ページ / コンテナのスクロール位置
- view timeline — 要素自身のビューポート進入率
最小サンプル: スクロール進捗バー
<div class="progress"></div>
<article>...長いコンテンツ...</article>
.progress {
position: fixed;
top: 0; left: 0;
height: 4px;
width: 100%;
background: orange;
transform-origin: left;
animation: grow linear;
animation-timeline: scroll(root); /* ページのスクロール */
}
@keyframes grow {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
これだけ。JS ゼロでスクロール進捗バーが動く。
最小サンプル: 要素が見えると現れる
.card {
animation: reveal linear;
animation-timeline: view();
animation-range: entry 0% cover 30%;
}
@keyframes reveal {
from { opacity: 0; transform: translateY(40px); }
to { opacity: 1; transform: translateY(0); }
}
このセクションの読み方
- 基本概念 — タイムライン / 進行度 / 範囲
- scroll() — スクロールベース
- view() — 要素のビューポート進入
- animation-range — 範囲指定
- 名前付きタイムライン — 関連付け
- JS / WAAPI — JS から使う
- 実践パターン — パララックス、リビール、進捗
- 運用と注意点
従来手法との比較
| 手法 | 長所 | 短所 |
|---|---|---|
| scroll イベント + JS | 柔軟 | 重い、ジャンク発生 |
| IntersectionObserver | 軽い | 「見えた / 見えない」だけ |
| GSAP ScrollTrigger | 強力 | ライブラリ依存 |
| animation-timeline | 標準・GPU・JS なし | 新しめ、対応ブラウザ |
関連セクション
- JS で自作するトゥイーン — 自前ループの理論
- View Transition API — ページ遷移補間
- SVG アニメーション
体感の違い
一度書いてみるとわかるが、scroll イベント + transform を JS で動かすやつとは滑らかさが別物。 コンポジタスレッドで動くため、メインスレッドが詰まっても引きずられない。