CSS animation-timeline: scroll()でJSなしのスクロールアニメーション
問題
ページのスクロールに応じて上部にプログレスバーを表示したい場合、通常はscrollイベントリスナーとrequestAnimationFrameを使います。動作はしますが、コードが長くなりパフォーマンスの調整も必要です。
解決方法
CSS animation-timeline: scroll()を使えば、JavaScriptは不要です。
.progress-bar {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 4px;
background: #3b82f6;
transform-origin: left;
animation: grow-progress linear;
animation-timeline: scroll();
}
@keyframes grow-progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
<div class="progress-bar"></div>
これだけです。animation-timeline: scroll()が、時間ベースではなくスクロール位置ベースでアニメーションを駆動します。
特定の要素がビューポートに入った時にアニメーションさせたい場合はview()を使います。
.fade-in {
animation: fade-in linear;
animation-timeline: view();
animation-range: entry 0% cover 40%;
}
@keyframes fade-in {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
animation-rangeで、アニメーションの開始・終了区間を細かく制御できます。entry、exit、cover、containなどのキーワードを組み合わせて使います。
ポイント
animation-timeline: scroll()はスクロール位置ベースのアニメーション、JSは不要ですview()は要素のビューポート進入・離脱に基づくアニメーションですanimation-rangeでアニメーション区間を精密に制御できますtransformとopacityのみ使えばコンポジタースレッドで動作し60fpsが保証されます- Chrome、Edge、Safari 18+で対応。Firefoxはまだフラグの裏にあります