運用と注意点
ブラウザサポート、polyfill、prefers-reduced-motion、パフォーマンス、デバッグ、 SEO や A11y への配慮まで。
ブラウザサポート(2026 年初頭)
| ブラウザ | 対応状況 |
|---|---|
| Chrome / Edge | 115+ 完全対応 |
| Opera | 完全対応 |
| Safari | 段階的対応中(基本は OK) |
| Firefox | フラグ付き / 標準対応進行中 |
| iOS Safari | 段階的 |
最新情報は caniuse.com で確認。
非対応環境への対応
1. 進化的強化(既定)
非対応ブラウザでは静的に表示される設計に。アニメは「あったらラッキー」程度の演出に留める。
.reveal {
opacity: 1; /* 既定(非対応では常に表示) */
}
@supports (animation-timeline: scroll()) {
.reveal {
opacity: 0;
animation: reveal linear both;
animation-timeline: view();
animation-range: entry 0% cover 30%;
}
}
2. polyfill
どうしても全環境で動かしたいなら scroll-timeline polyfill を導入:
npm install scroll-timeline-polyfill
- JS で scroll を拾うためネイティブよりは重い
- 互換性は完璧ではない
- 初期表示時のレイアウトに気を付ける
prefers-reduced-motion
必須。OS で「視差効果を減らす」を有効にしているユーザは VR 酔い等の問題を抱えている。
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
.reveal {
opacity: 1 !important;
transform: none !important;
}
}
パフォーマンス
動かすプロパティ
- ◎ transform / opacity — GPU 加速
- ○ filter — GPU だが重め
- × top / left / width / height — レイアウト発生で重い
- × background-color の頻繁変更 — ペイント発生
大量要素
- scroll-driven はコンポジタスレッドで動くので、メインスレッドが詰まっても進む
- ただし合成レイヤが多すぎるとメモリ圧迫
- 必要なところだけ
will-change
will-change
.reveal {
will-change: transform, opacity;
}
付けすぎ注意。アニメ完了後に外すのが理想。
レイアウトシフト(CLS)
- 初期値で位置が変わるとレイアウトシフト
transform/opacityはシフトしないheight: 0からheight: autoはシフト発生 → NG
デバッグ
- Chrome DevToolsAnimations パネル — scroll-timeline 表示
- Style → Animations の歯車から速度調整
- Application タブでScrollTimeline を確認
- CSS
--debug変数 + outline でターゲット可視化
SEO / アクセシビリティ
- 初期状態でコンテンツが読める(opacity: 0 で隠したまま放置 NG)
- 視差効果でユーザを混乱させない
- スクリーンリーダは scroll-driven の影響なし(DOM がある限り読める)
- Reduce Motion 対応必須
動的なコンテンツ
- SPA で要素が後から追加されると、CSS は自動で適用される
- 名前付きタイムラインは要素マウント時に解決
- JS で
animate()する場合は要素生成後に
iOS Safari の注意点
- スクロールバーの挙動が違う
- ゴムバンド(バウンス)でタイムラインが想定外に進む可能性
- 慣性スクロール後のジャンプに注意
- テスト必須
polyfill のチューニング
- 使う要素を最小限に
- 必要なところだけ
document.startViewTransition等 - scroll イベントを passive: true で
典型的なバグ
| 症状 | 原因 |
|---|---|
| 初期で見えてしまう | opacity: 0 の初期値漏れ / @supports 未使用 |
| 動かない | scroll の対象が overflow:hidden / 高さ不足 |
| fill-mode 抜けで戻る | both または forwards を付ける |
| レイアウトシフト | height や padding を動かしている |
| 名前が解決しない | timeline-scope を親に |
本番チェックリスト
- ☐ @supports でフォールバック
- ☐ prefers-reduced-motion 対応
- ☐ 初期値が CLS を引き起こさない
- ☐ transform / opacity 中心に動かす
- ☐ 不要な animation は付けない(過剰演出)
- ☐ iOS / Android / 各ブラウザで実機確認
- ☐ Lighthouse でパフォーマンス計測
関連リソース
- Chrome: Scroll-driven animations
- Bram.us scroll-driven animations
- CSS Scroll-linked Animations 仕様
- scroll-timeline polyfill
本セクションの総まとめ
- scroll() でスクロール量、view() で要素のビューポート進入
- animation-range で実際の発動範囲を絞る
- 名前付きタイムラインで離れた要素同士を連動
- JS / WAAPI から動的に
- 非対応ブラウザは進化的強化 / polyfill
- Reduce Motion を絶対忘れない
最後に
scroll-driven animations は「JS なしでスクロール演出」という長年の夢。 すでに実用域に入っている。今後は GSAP ScrollTrigger 並みの機能が CSS だけで書けるようになる流れ。 先取りで触っておくとアドバンテージになる。