スクロール駆動アニメーション(Scroll-driven Animations)を使うと、スクロール量そのものをアニメーションの進捗に使えます。スクロールと完全に連動して動くスクラブアニメーションや、スティッキーな表現をCSSだけで実装できるのが特徴です。
CSSで作るスクロールアニメーションには、一般的に次の2種類があります。
- スクロール駆動アニメーション:スクロール量に連動して進む
- スクロールトリガーアニメーション:スクロール位置をきっかけに、時間で進む
本記事で紹介するのは前者です。たとえば次のようなスクロールアニメーションを作れます。JavaScriptは使用していません。

スクロールアニメーションを使うメリットと注意点
スクロールアニメーションには、次のようなメリットがあります。
- コンテンツの視線誘導に役立つ
- ウェブサイトの没入感の向上に役立つ
効果的なアニメーションは、優れたユーザー体験を提供する一助となるでしょう。一方、利用者の中にはアニメーションが苦手であったり、画面酔いしやすい方もいます。
スクロールアニメーションが苦手な方のために、モーション軽減設定に配慮した実装も検討するといいでしょう。記事『CSSでもアクセシビリティに配慮しよう! モーション軽減・文字サイズ変更・ダークモードの実装方法』にて解説していますので、ぜひご覧ください。
スクロール駆動アニメーション
スクロール駆動アニメーションでは、連動させるスクロール範囲に応じて、次のタイムラインを使い分けます。
- スクロール進捗タイムライン(Scroll Progress Timeline):スクロールコンテナー全体の進捗を表す。
scroll()関数で指定する - ビュー進捗タイムライン(View Progress Timeline):対象要素がスクロールポートを通過する進捗を表す。
view()関数で指定する
スクロール進捗タイムライン
スクロール進捗タイムラインは、スクロールコンテナーの先頭から末尾までを0%から100%の進捗として扱います。
次の作例のように、ページのスクロール進捗に連動して、要素が垂直方向にスケールアップするスクラブアニメーションを作ります。
▼左:紹介するデモ、右:アレンジバージョン

① 事前準備:アニメーションさせる要素(div.animationElement)を用意し、スクロールが発生するようbody要素に適当な高さを確保しておきます。
<div class="animationElement"></div>
body {
height: 200vh; /* スクロールが発生するよう適当な高さを確保 */
}
②@keyframesルールでアニメーションを用意し、アニメーションさせる要素に指定します。
/* 垂直方向にスケールを変えるキーフレーム */
@keyframes grow-progress {
from {
scale: 1 0;
}
to {
scale: 1 1;
}
}
③animation-timelineプロパティにscroll()関数を指定します。
.animationElement {
/* スタイリング */
position: fixed;
width: 100px;
height: 100px;
background: royalblue;
transform-origin: bottom; /* 下部を変形の基準にしておく */
/* スクロールアニメーションの設定 */
animation: grow-progress linear; /* アニメーションを指定。イージングはlinear */
animation-timeline: scroll();
}
たった数行のCSSで、スクラブアニメーションの完成です。
ビュー進捗タイムライン
ビュー進捗タイムラインは、対象要素がスクロールポートを通過する範囲を0%から100%の進捗として扱います。
続いて、以下の作例のようにスクロールを進めて画面内にアニメーション要素が入ってきた時にマスクが動くスクラブアニメーションを作ります。

①事前準備:アニメーションさせる要素(div.animationElement)を用意し、スクロールが発生するよう前後に適当な高さを確保した要素(div.skeleton)を配置しておきます。
<div class="skeleton">スクロールを発生させるため適当なエリアを確保しています</div>
<img class="animationElement" src="./images/sapphire.webp" alt="サファイア" width="300" height="300">
<div class="skeleton">スクロールを発生させるため適当なエリアを確保しています</div>
.skeleton {
height: 100vh; /* スクロールが発生するよう適当な高さを確保 */
}
②@keyframesルールでアニメーションを用意し、アニメーションさせる要素に指定します。
今回はマスクを使うアニメーションを作ります。
/* 円→(角丸四角形を経由)→正方形 にマスクの形状を変化させるキーフレーム */
@keyframes reveal-image {
from {
clip-path: inset(30% round 20%);
}
to {
clip-path: inset(0);
}
}
③animation-timelineプロパティにview()関数を指定します。
④animation-rangeプロパティを設定します。
アニメーションさせる画像がビューポートに完全に入った時点(contain 0%)でアニメーションを開始し、画像がビューポートの真ん中まで来た時(contain 50%)にアニメーションを終了するよう範囲を指定します。
.animationElement {
/* スクロールアニメーションの設定 */
animation: reveal-image linear both; /* アニメーションを指定。イージングはlinear。animation-fill-modeはboth */
animation-timeline: view();
animation-range: contain 0% contain 50%; /* 開始: 要素がビューポートに完全に入った時、終了: ビューポートの真ん中 */
}
また、animation-rangeプロパティに指定できる値は種類が多く複雑ですので、View Timeline Ranges Visualizerツールが理解の助けになるでしょう。値を変えて試すことができ、わかりやすく視覚化されているのでぜひご活用ください。
▼animation-range: contain 0% contain 50%;を指定した例

作例:スティッキーとの組み合わせ
ここまで紹介した2種類のタイムラインを使い、スティッキーな表現やパララックスを組み合わせた作例です。物語の一部を用い、没入感が生まれるような装飾とアニメーションを施しました。
▼スクロール駆動アニメーションの作例ページ

作例中でアニメーションの進捗に使っているのは、スクロール進捗タイムライン(scroll())かビュー進捗タイムライン(view())です。詳しくはサンプルコードをご確認ください。
対応ブラウザ
スクロール駆動アニメーションで使うanimation-timelineは、Chrome・Edge 115(2023年7月)、Safari 26.0(2025年9月)、Firefox 159(2026年10月)以上が対応しています。
参照:Can I use…
まとめ
CSSだけで作れるスクロール駆動アニメーションを紹介しました。作りたいと思ったアニメーションが、手軽に実装できるようになったのではないでしょうか。実装のハードルが下がった分、今後はどのようなアニメーションを作るかが重要になりそうですね!
もうひとつの、スクロールトリガーアニメーションは後続記事『CSSだけでつくる! スクロールトリガーアニメーション』で紹介します。ぜひご覧ください!
※この記事が公開されたのは3年前ですが、先月10月に内容をメンテナンスしています。


