【CSS】スクロールと連動するアニメーションをJavaScriptを使わずに実装してみる
はじめに
アニメーションをスクロールと連動させる際には、基本的にJavaScriptが必要になります。しかし、Scroll-driven Animationsを使用することによって、なんとCSSだけで実装できるようになります。「リッチなアニメーションを実装したいんだけど、JavaScriptには苦手意識があって...」というような方にとっては救世主になるのではないでしょうか。
この記事では、Scroll-driven Animationsの基本的な使い方やサンプルについて解説します。
そもそもScrol-driven Animationsって?
Scroll-driven AnimationsはChrome115で実装された新機能です。シンプルなCSSだけで、スクロール量と連動したアニメーション(スクラブアニメーション)を実装できるようになりました。実装の手軽さだけでなく、JavaScriptを使わないことによるページパフォーマンスの向上も期待できます。
このアニメーションのタイムラインには2つの種類があります。
- Scroll Progress Timeline
- View Progress Timeline
これらを使い分けることで、異なった挙動のアニメーションが実装できます。
Scroll Progress Timeline
スクロールできるコンテナ全体を基準にしたもの。スクロールの開始位置を0%・終了位置を100%として、アニメーションの進捗を管理します。
サンプル
ブログ系のサイトでたまに見かける読了率メーターを実装します。
任意の要素に対し、水平方向のscale
を0
から1
へアニメーションさせます。
アニメーションの内容自体はkeyframesで定義しておきます。animation-timeline
プロパティにscroll()
を指定することで、定義したアニメーションをスクロールと連動させることができます。
<body>
<div class="progress">
<div class="progress-bg"></div> <!-- 進捗バーの背景 -->
<div class="progress-bar"></div> <!-- 進捗バー本体 -->
</div>
</body>
/* Scroll Progress Timeline */
/* 進捗バー本体(これのサイズを変動させます) */
.progress-bar {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 12px;
background-color: darkorange;
transform-origin: left center;
animation: readingProgress linear;
animation-timeline: scroll(); /* アニメーションタイムライン scroll()を指定 */
}
/* 進捗バーの背景(なくても構いません) */
.progress-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 12px;
background-color: #ccc;
}
/* 水平方向にサイズを変動 */
@keyframes readingProgress {
from {
scale: 0 1;
}
to {
scale: 1 1;
}
}
※ bodyの高さを指定するなどして、ある程度スクロールできるよう調整してください。
View Progress Timeline
ビューポートを基準にしたもの。ビューポートの最下端を0%、反対側の端に到達すると100%としてアニメーションの進捗を管理します。
サンプル
画面内に要素が入ってきた時に、スクロールと連動して要素を回転させる仕組みを実装します。
任意の要素のrotate()
を0
から180deg
にアニメーションさせます。Scroll Progressと同様に、アニメーションの内容自体はkeyframesで定義し、あとはanimation-timelineにview()
を指定すればOKです。
また、今回はanimation-rangeというプロパティによりアニメーションの開始位置と終了位置の微調整を行うことが可能です。MDNの解説を見ていただければ分かるとおり、値が多数あり複雑です。View Timeline Ranges Visualizerというツールを使うと、イメージも湧きやすく実装の助けになるかと思われます。
<body>
<div class="rotate"></div>
</body>
/* View Progress Timeline */
.rotate {
position: relative;
width: 240px;
aspect-ratio: 1/1;
margin: 4em auto;
background-color: darkorange;
animation: circle linear both;
animation-timeline: view(); /* アニメーションタイムライン view()を指定 */
animation-range: cover 0% cover 50%; /* 開始: 要素がビューポートに完全に入った時、終了: ビューポートの真ん中 */
}
/* 回転 */
@keyframes rotate {
from {
transform: rotate(0);
}
to {
transform: rotate(180deg);
}
}
※ bodyの高さを指定するなどして、ある程度スクロールできるよう調整してください。
対応ブラウザ
2024年6月17日現在、ブラウザの対応状況は以下のようになっています。
Safari・Firefoxではまだ対応が進んでいないようですね。
まとめ
CSSだけを使ってスクラブアニメーションを実装する方法について解説しました。先述したように、まだ全てのモダンブラウザが対応しているわけではありませんが、時間の問題ではないでしょうか。今のうちに様々な演出を試してみてはいかがでしょう。
参考サイト
今回の記事を作成するにあたり参考にさせていただきました。ありがとうございます!
Discussion