クリエイターラボ

CSSだけで実装するスクロールアニメーション Scroll-driven Animations

良かったら”♥”を押してね!

はじめに

Javascriptを書かなくてもスクロールアニメーションが実装可能なCSSの機能『Scroll-driven Animations』を今回はご紹介します。

このCSSの機能は今までJavaScriptでスクロールアニメーションを実装していた私からすると結構凄くて、従来の書き方と今回紹介する書き方を比較すると、

■従来↓

JavaScript

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.add('fade-in');
    }
  });
});

document.querySelectorAll('.card').forEach(card => {
  observer.observe(card);
});

CSS

.card {
  opacity: 0;
  transform: translateY(50px);
  transition: all 0.6s;
}

.card.fade-in {
  opacity: 1;
  transform: translateY(0);
}


■新しい方法

.card {

  animation: fade-in linear;
  animation-timeline: view();
  animation-range: entry 0% cover 30%;
}

@keyframes fade-in {
  from {
    opacity: 0;
    transform: translateY(50px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

このように簡単なフェードインアニメーションを実装するだけでも結構な記述量の違いが生まれてきます。従来だとJavaScriptとcssの両方を書かないといけないですからね。

CSSだけで完結するのも管理しやすくてありがたいですね。

必要となるCSSの解説

基本的な実装方法を見ていきましょう。

animation

animation-timeline

animation-range


基本的に必要なCSSはこの3つとなります。

animation

こちらについてはホームページでのcssアニメーションをする際にマストのものなのでご存知の方も多いと思います。

アニメーション名イージングを設定するものです。アニメーションの名前を任意で決めて、どういう動き方にするか決めるわけですね。

実装例↓

animation: fade-in linear;

因みにイージングの種類は下記の通りです。

ご参考にしてください。

動き
linear等速(スクロールと同じ速度)
easeゆっくり始まってゆっくり終わる
ease-inゆっくり始まる
ease-outゆっくり終わる

animation-timeline

ここがCSSスクロールアニメーションの核となります。

何を監視するかをここで決めています。アニメーションの引き金となるものを決めているとも言えると思います。(逆にわかりづらかったらごめんなさい・・・。)


主な使い方は2つあります。

① view()

要素が画面に入ったかを監視しています。
実装例↓

animation-timeline: view();
animation-timeline: view(block 100px 0px);
animation-timeline: view(block 100px 50px);

2行目と3行目の意味としましては

2行目→『要素の上から100px内側のところから監視する。』
3行目→『要素の上から100px内側のところから要素の下から50px内側のところまでを監視する。』

という意味です。ここまで詳細に位置を指定できるのはありがたいですね。簡単なアニメーションであれば本当にJSは要らなそうです。

② scroll()

スクロール量を監視しています。

animation-timeline: scroll(root);
animation-timeline: scroll(nearest);
animation-timeline: scroll(self);

scroll(root)ページ全体のスクロール量を監視。因みにrootがデフォルト値なので、書かなくて良いです。

scroll(nearest)自分の一個上の階層の親要素のスクロール量。親要素のスクロール量によって自分自身の状態が変わるときに使います。例えばモーダルウインドウ(親)を開いていて、スクロールするごとにプログレスバー(自分自身)が進んだりするときなどに有効ですね。

scroll(self)自分自身のスクロール量。その要素自体のスクロール量と言えば良いでしょうか。スクロール量によって自分の背景色を変えるときに使ったりします。

animation-range

最後にanimation-rangeいつアニメーションを開始・終了するかを指定します。 ここでアニメーションのタイミングを細かくコントロールできるわけですね。

実装例↓

animation-range: entry 0% cover 30%;

主なキーワードは下記の通りです↓

キーワードタイミング
entry要素が画面に入り始めた
exit要素が画面から出始めた
cover要素が画面を覆っている範囲
contain要素が画面内に完全に見えている

それぞれ見ていきます。

entry
animation-range: entry 0% entry 100%;
animation-range: entry 0% entry 50%;

1行目 → 『要素が画面に入り始め(0%)たらアニメーションを開始して、完全に入った(100%)らアニメーション終了

2行目 → 『要素が画面に入り始め(0%)たらアニメーションを開始して、半分まで入った(50%)らアニメーション終了

といった感じです。

Exit

要素が画面から出始めた時を指します。

animation-range: exit 0% exit 100%;

↑の例で言えば、『要素が画面から出始めて(0%)からアニメーションを開始して、完全に出終わった(100%)タイミングでアニメーション終了』という意味です。

cover

要素が画面と重なっている全期間を指します。イメージとしては、要素が「画面に入り始めてから、完全に出るまでの全体」です。entryとexitのどちらも包括しているような感じですね。

contain

要素が画面内に完全に見えている時を指します。 これは要素が画面の上端から下端まで完全に収まっている状態です。

animation-range: contain 0% contain 100%;
animation-range: contain 20% contain 80%;

1行目 → 『要素が完全に見え始めて(0%)からアニメーションを開始して、完全に見えているところの手前(100%)でアニメーション終了

2行目 → 『要素が完全に見え始めて20%進んだところからアニメーションを開始して、完全に見え始めて80%進んだところでアニメーション終了


最初、coverとcontainの違いがわからないと思っていたのですが、
contain → 要素が完全に見えている期間だけ
cover → 要素が画面と重なっている全期間
という認識で良いかと思います。

実践編

ここまで押さえていれば、実践に入って良いと思います。

ここからは実際に使えるアニメーションパターンを紹介していきます。

例①:view() を使ったカードのフェードイン

最頻出と言って良いくらいの要素が画面に入ってきたらふわっと表示されるアニメーションですね。


ポイント

animation-timeline: view()で各カードが画面に入ったかを監視して、
animation-range: entry 0% cover 50%で画面に入り始めてから全体の50%まで表示される間アニメーションをしています。

例②:scroll() を使った読了率バー

ページ全体のスクロール量に応じてバーが伸びるプログレスバーです。


ポイント↓

animation-timeline: scroll(root)でページ全体のスクロール量を監視

スクロール0%でscaleX(0)(バーの幅0%)

スクロール100%でscaleX(1)(バーの幅100%)

最後に

これで以上です。

同じスクロールアニメーションでももっと複雑な動きが求められるようであればまだまだJavaScriptでの記述が必要になるかと思いますが、そこまで複雑でないものであればこのCSSの機能だけで事足りそうです。

使いこなしてホームページ制作の効率化にどんどん繋げていきましょう!

良かったら””を押してね!
person_editこの記事を書いた人
コーダー いとう いなり
プロフィール写真

2022年入社。東進ハイスクールの現代文講師林修先生を敬愛してやまないコーダー。林先生に負けないくらいの知的好奇心や探求心を武器にホームページ制作に役立つ有益な情報を発信する。好きな食べ物はいなりです。

この人が書いた記事をもっと見る

目次へ戻る