【コピペ可能】スクロールアニメーションの解説と実装方法

【コピペ可能】スクロールアニメーションの解説と実装方法

記事の概要

Webサイトのアニメーションで、次の2つをよくみるのではないでしょうか。 「スクロールしたら出現する」 「スクロールの量に応じて変化する」 この2つスクロールアニメーションの方法について、この記事では解説します。

紹介するコードはそのままコピペして利用可能ですので、ぜひ参考にしてください。

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

スクロールアニメーションとは、ユーザーのスクロールを起点として動くアニメーションのことです。
例えば、スクロールしていくとふわっと画像が出てくるや、スクロール量に応じてアイコンが動くなどです。

このスクロールアニメーションは、ほとんどのサイトで使われており、工夫次第で色々な動きを表現することが可能です。

スクロールアニメーションの基本

スクロールアニメーションの仕組み

ざっくりとスクロールアニメーションについて説明しましたが、このスクロールアニメーションの仕組みについてお話しします。

仕組みとしては、「イベント発火の制御」、「アニメーションの制御」の2つに分かれています。

イベント発火の制御とは、ユーザーの操作によって「要素が画面に入った」や「どれだけスクロールされた」ということを検知・アニメーションの開始をJavaScriptで行います。

アニメーションの制御とは、イベント発火によって、どんなアニメーションにするのかということをCSSやJavaScriptで調整します。

この記事では、イベント発火のJavaScriptコード、基本的なアニメーションのCSSコードを紹介します。

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

スクロールして動くアニメーションは、いろいろなものがありますが、具体的なイベント発火の制御としては大きく以下の2つがほとんどです。

  • 特定の要素が、画面内に入ったら特定のクラス名をつける
  • 特定の要素が、画面内でスクロールした量に応じて特定のカスタムプロパティの値を変化させる

このイベント発火の制御がスクロールアニメーションのキモとなります。
JavaScriptが必要となるため、少しハードルを感じるかもしれませんが、コードを使い回すことが可能です。このあと、コードサンプルも紹介しているのでコピペや編集してご利用ください

アニメーションの動きの部分は、クラス名やカスタムプロパティを使ってCSSやJavaScriptで発想次第で色々な動きを表現できます。

CSSの進化

近年CSSが進化しており、このイベントの発火もCSSで制御することができるようになっています。

ただ、対応しているブラウザ、バージョンが限られており、現時点(2025/9)では、使うことはあまりお勧めできません。

この点は人によって考えが異なるかもしれません。

私はWebの一番のいい点として、「誰もがどこでも平等に同じ情報を得られる」ということだと考えているため、一部のユーザーしか見ることができない実装というのは積極的に行うべきではないと思います。

スクロールアニメーションの参考コード

JavaScript(イベントの発火)

特定の要素が画面内に入ったら、特定のクラス名を付与するコード。


const targets = document.querySelectorAll('.js-scroll-anim');

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

targets.forEach(target => observer.observe(target));

js-scroll-animというクラスを持つ要素を全て取得し、IntersectionObserverで画面内に入ったかどうかを監視します。画面内に入ったものにはis-animatedというクラスを付与するコードです。

動かしたい要素にjs-scroll-animというクラス名を付け、is-animatedというクラスを使ってCSSで動きをつけるとスクロールアニメーションができます。

特定の要素が、画面内でスクロールした量に応じて特定のカスタムプロパティの値を変化させるコード。


const targets = document.querySelectorAll('.js-progress');

window.addEventListener('scroll', () => {
  targets.forEach(el => {
    const rect = el.getBoundingClientRect();
    const windowHeight = window.innerHeight;

    // スタート・エンド位置(%指定)
    const start = windowHeight * 0.8; // 画面の80%
    const end   = windowHeight * 0.2; // 画面の20%

    // 要素の先頭が画面内のどこにあるか(px)
    const elementTop = rect.top;

    // 0〜1の範囲で正規化
    let progress = (start - elementTop) / (start - end);

    // 0未満→0, 1超→1 に丸める
    progress = Math.min(Math.max(progress, 0), 1);

    // CSS変数に反映
    el.style.setProperty('--progress', progress);
  });
});

js-scroll-progressというクラスを持つ要素を全て取得し、スクロールイベントで対象の要素に–progressというカスタムプロパティをセットし、要素が画面内の上端80%位置に来た時を0、画面内の上端から20%の位置に来た時を1となるようにプロパティの値を変化させるコードです。
(画面のどの位置というのはコード内のstart, endの変数で制御可能です。)

スクロール量に応じた動きをつけたい要素に、js-scroll-progressというクラス名を付与し、その要素のCSSのプロパティの値に--progressを使えばスクロール量に応じたアニメーションが可能です。

CSS(アニメーションの動き)

次にいくつかアニメーションのサンプルを紹介します。

画面内に入ったらフェードインする

イベント発火クラス


.fade-in {
  opacity: 0;
  transition: opacity 0.6s ease;
  will-change: opacity;
}
.fade-in.is-animated {
  opacity: 1;
}

画面内に入ったらスライドインする


.slide-in-up {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.6s ease, transform 0.6s ease;
  will-change: opacity, transform;
}
.slide-in-up.is-animated {
  opacity: 1;
  transform: translateY(0);
}

画面内に入ったらズームインする


.zoom-in {
  opacity: 0;
  transform: scale(0.8);
  transition: opacity 0.6s ease, transform 0.6s ease;
  will-change: opacity, transform;
}
.zoom-in.is-animated {
  opacity: 1;
  transform: scale(1);
}

スクロール量に応じて、じわじわ表示される


.fade-in-progress {
  opacity: var(--progress, 1);
}

スクロール量に応じて、スライドインする


.slide-in-up-progress {
  opacity: var(--progress, 1);
  transform: translateY(calc(30px * ( 1 - var(--progress, 1))));
}

スクロール量に応じて、ズームインする


.zoom-in-progress {
  opacity: var(--progress, 1);
  transform: scale(calc(0.8 * (1 - var(--progress))));
}

さいごに

スクロールアニメーションについて解説しましたが、仕組みを理解することで「意外と簡単だったんだ」とか、「こんなこともできるかも・・」と感じていただければ嬉しいです。

いくつかコードを紹介しましたが、あくまで実装方法の一例であることご理解いただきますようお願いします。JavaScriptもスクロールイベントを使っていますが、もっと効率の良い書き方もあると思います。

応用アイデア

今回紹介したのは基本的なフェードインやスライドですが、
--progress をうまく使えば、拡大・回転・色変化・ぼかしなど、自由自在にコントロールできます。
ぜひデザインに合わせてアレンジしてみてください。

Teppei

webコーダー teppei

兵庫県神戸市を拠点に"Webコーダー"としてWebサイト構築を行っております。 前職はシステムエンジニアとして、プロジェクトマネージャーからプログラマーまで上流から下流のポジションを経験しました。システム導入、フロントエンド、バックエンドの開発に携わった経験を元に、Webサイトのコーディングのサポートをいたします。

お問い合わせ Contact

制作のご依頼やその他ご相談は、お問い合わせフォームにて受け付けております。

お問い合わせフォームへ