CSSだけでスクロールアニメーションが作れる!?
新技術Scroll-driven Animationsとは

69

2023年7月にリリースされたGoogle Chrome 115では、「Scroll-driven Animations」が搭載されました。 Scroll-driven Animationsを使うと、今まではJavaScriptを使わなければ実装できなかったスクロールと連動するようなアニメーションがCSSだけで実現できるようになります。

以下は、CSSだけを使って作成したスクロールアニメーションのデモです。一切JavaScriptは使用していません。

Scroll-driven Animationsの作例

Scroll-driven AnimationsはJavaScriptでも使うこともできますが、本記事では、実装の手軽さを一番にお伝えしたいため、CSSだけを使ったスクロール駆動アニメーションの作り方をご紹介します。

スクロールアニメーションとは

作り始める前に、まずはスクロールアニメーションについて整理しておきましょう。

メリットとユーザー設定に応じた対策

スクロールアニメーションをウェブサイトに導入する理由は複数あると考えられますが、以下のようなメリットが挙げられます。

  • コンテンツの視線誘導に役立つ
  • ウェブサイトの没入感の向上に役立つ

効果的なアニメーションは、優れたユーザー体験を提供する一助となるでしょう。

しかしながら、利用者の中にはアニメーションが苦手であったり画面酔いしやすい方などもいます。

スクロールアニメーションが苦手な方のために、reduced motionに配慮した実装も検討するといいでしょう。記事『ウェブサイトに演出は不要!? ユーザー設定にレスポンシブ対応できる新しいCSS』にて解説していますので、ぜひご覧ください。

スクロールアニメーションの種類

スクロールアニメーションはいくつかの種類に分類されます。記事『トレンドウェブサイトから学べ! JavaScriptで作る本格スクロール演出』にて紹介しているのは、次のような分類です。

  • スクロールで発火するアニメーション(トリガーアニメーション):アニメーションは時間で行われる
  • スクロールに連動したアニメーション(スクラブアニメーション):アニメーションはスクロール進捗量と連動して行われる
  • 一定時間固定されるアニメーション(スティッキーな表現):アニメーションはスクロール進捗量と連動して行われる

今回紹介する、animation-timelineanimation-rangeといった新しいCSSのプロパティを使って実装するスクロールアニメーションは、スクロール進捗量と連動してアニメーションさせるものです。スクラブアニメーションやスティッキーな表現を作ることができます。

作り方

それでは作り方をご紹介します。後述の対応ブラウザ以外は動作しませんのでバージョンにご注意ください。

ページのスクロール進捗に連動するスクラブアニメーションの実装(Scroll Progress Timeline)

次の作例のように、ページのスクロール進捗に連動して、要素が垂直方向にスケールアップするスクラブアニメーションを作ります。

▼左:紹介するデモ、右:アレンジバージョン ページのスクロールに連動するスクラブアニメーションのデモ

① 事前準備:アニメーションさせる要素(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で、スクラブアニメーションの完成です。

scroll()関数の詳しい構文はMDNのscroll()の解説を参照ください。

※Scroll Progress Timelineに関する補足:MDNの日本語ページで紹介されている、アットルールを使用した@scroll-timelineは古い構文ですのでご注意ください。新しい構文は、ドキュメントをご確認ください。

画面内に要素が入ってきた時にスクロールと連動するスクラブアニメーションの実装(View Progress Timeline)

続いて、以下の作例のようにスクロールを進めて画面内にアニメーション要素が入ってきた時にマスクが動くスクラブアニメーションを作ります。

ページのスクロールに連動するスクラブアニメーションのデモ

①事前準備:アニメーションさせる要素(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ルールでアニメーションを用意し、アニメーションさせる要素に指定します。

今回はマスクを使うアニメーションを作ります。

マスクについては記事『変幻自在なグラフィック表現! CSS, SVG, Canvasでマスクを使いこなせ』にて解説しています。

/* 円→(角丸四角形を経由)→正方形 にマスクの形状を変化させるキーフレーム */
@keyframes reveal-image {
  from {
    clip-path: inset(30% round 20%);
  }
  to {
    clip-path: inset(0);
  }
}

animation-timelineプロパティにview()関数を指定します。

view()関数の詳しい構文はMDNのview()の解説を参照ください。

animation-rangeプロパティを設定します。

アニメーションさせる画像がビューポートに完全に入った時点(contain 0%)でアニメーションを開始し、画像がビューポートの真ん中まで来た時(contain 50%)にアニメーションを終了するよう範囲を指定します。

animation-rangeプロパティに指定できる値については、MDNのanimation-rangeの解説を参照ください。

.animationElement {
  /* スクロールアニメーションの設定 */
  animation: reveal-image linear both; /* アニメーションを指定。イージングはlinear。animation-fill-modeはboth */
  animation-timeline: view();
  animation-range: contain 0% contain 50%; /* 開始: 要素がビューポートに完全に入った時、終了: ビューポートの真ん中 */
}

今回も同様に、たった数行のCSSでスクラブアニメーションが完成しました。

また、animation-rangeプロパティに指定できる値は種類が多く複雑ですので、View Timeline Ranges Visualizerツールが理解の助けになるでしょう。値を変えて試すことができ、わかりやすく視覚化されているのでぜひご活用ください。

animation-range: contain 0% contain 50%;を指定した例 View Timeline Ranges Visualizer

そのほかの作例

作り方のセクションにて紹介したデモに加え、新たにスティッキーな表現と組み合わせる動き・パララックス的なアニメーションを追加したデモです。物語の一部を用いており、没入感が生まれるような装飾とアニメーションを施しました。

▼Scroll-driven Animationsの作例ページ Scroll-driven Animationsの作例

色々な種類のアニメーションを使用しましたが、アニメーションとスクロールを連動させる部分は、スクロールタイムライン(scroll()関数)かビュータイムライン(view()関数)のどちらかであることがわかるかと思います。

前述の作り方とおおよそ同じ内容になるので解説は省略いたします。作例中のアニメーションについて詳しく知りたい方はサンプルコードをご確認ください。

Codepenの作例

CodepenにはScroll-driven Animationsを使ってCSSだけで作られたデモがいくつかあります。

新技術であるためまだCodepenにアップロードされているデモの数は少ないですが、CSSだけでどのようなアニメーションが作れるのかが参考になるでしょう。

左上右上左下右下

Codepen - Scroll-driven Animationsのデモ

また、どのようなアニメーションを作るかインスピレーションを得たい場合には、従来のJavaScriptによって実装されたスクラブアニメーションの作例なども参考にできます。

どのようなアニメーションが行われているか、どれくらいのスクロール量でアニメーションしていそうかを観察すれば、CSSに置き換えられるかもしれません。

対応ブラウザ

対応ブラウザは以下の通りです。Chrome 115・Edge 115(2023年7月リリース)以上のみ対応しています。

非対応のブラウザや非対応のバージョンでは残念ながらアニメーションは再生されませんが表示自体はされます。対応ブラウザだけでも使ってみたい場合は取り入れてみてはいかがでしょうか。

“animation-timeline” | Can I use…(Scroll-driven Animationsで使用するanimation-timelineプロパティを検索しています)

animation-timelineプロパティが使えるブラウザの表

まとめ

CSSだけを使って作れるスクロール駆動アニメーションについてご紹介しました。作りたいと思ったアニメーションが、手軽に実装できるようになったのではないでしょうか。

実装のハードルが下がった分、今後はどのようなアニメーションを作るかが重要になりそうです。

まだすべてのブラウザが対応していませんが閲覧環境を気にせず使える日が来るといいですね!  スクロールアニメーションだけでも参考になれば幸いです。

参考サイト

※この記事が公開されたのは1年前ですが、先月11月に内容をメンテナンスしています。

澤田 悠

フロントエンドエンジニア。大学はデザイン専攻だったもののコードから作りたくてICSへ。趣味は、お絵描き・CG・美術館巡りです。

この担当の記事一覧