【JavaScript】スクロールして要素が画面内に入ったときにふわっと表示されるアニメーションを実装する

スクロール連動フェードインアニメーション アイキャッチ

Webサイトをスクロールした際、要素が画面内に入ったタイミングで下から「ふわっ」と浮き上がるように現れるフェードインアニメーション。ユーザーの視線を自然に引きつけ、サイト全体に洗練された印象を与える定番のUI演出です。この記事では、jQueryなどの外部ライブラリを使わず、JavaScriptとCSSのみでシンプルに実装する方法を分かりやすく解説します。

スクロールアニメーションのBefore/After画面キャプチャ
▲ スクロール前後の動作イメージ(画面に入った瞬間にクラスが付与され、下から滑らかにフェードイン)

HTMLの準備

まずは、アニメーションを適用したいHTML要素にクラス名を指定します。ここではクラス名を「fade-in-element」として設定します。

HTML
index.html
<!-- アニメーション対象の要素にクラス名を指定 -->
<div class="fade-in-element">
  <h3>ふわっと表示されるタイトル</h3>
  <p>スクロールして画面内に入ると、下から自然にフェードインして表示されます。</p>
</div>

このクラス名を目印として、後ほどCSSで初期スタイルを定義し、JavaScriptで画面内進入を監視します。

CSSの設定とプロパティの解説

CSSでは、「初期状態(透明で少し下にある状態)」と「表示後(不透明で定位置にある状態)」の2つのスタイルを定義します。

CSS
style.css
/* 初期状態:透明にして20px下に配置 */
.fade-in-element {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.5s ease-out, transform 0.5s ease-out;
}

/* 画面内に入ったとき(JavaScriptで追加されるクラス) */
.fade-in-element.is-visible {
  opacity: 1;
  transform: translateY(0);
}

使用しているCSSプロパティのポイント

  • opacity: 0 / 1:不透明度を指定します。初期状態は「0(透明)」にしておき、表示時に「1(通常表示)」へ切り替えます。
  • transform: translateY(20px) / (0):垂直方向の位置を移動します。初期状態を「20px下」にずらしておき、表示時に「0(本来の位置)」に戻すことで、下からふわっと浮き上がる自然な動きが生まれます。
  • transition:プロパティが変化する際の所要時間や動き方を指定します。「0.5s ease-out」とすることで、0.5秒かけて滑らかに変化し、到着時にふわりと減速する上品なフェードインに仕上がります。

JavaScriptで画面内判定とクラス付与を実装

次に、JavaScriptを用いてスクロールイベントを監視し、要素がブラウザの表示領域に入った瞬間に「is-visible」クラスを付与します。

JavaScript
main.js
document.addEventListener('DOMContentLoaded', () => {
  // 1. 対象の要素をすべて取得
  const elements = document.querySelectorAll('.fade-in-element');

  // 2. スクロール時に画面内に入ったかを判定する関数
  const onScroll = () => {
    elements.forEach(element => {
      // 要素のビューポート相対位置を取得
      const rect = element.getBoundingClientRect();

      // 要素の上端が画面の表示領域(下端)より上に入った場合
      if (rect.top < window.innerHeight) {
        element.classList.add('is-visible');
      }
    });
  };

  // 3. スクロールイベントに関数を登録
  window.addEventListener('scroll', onScroll);

  // 4. 初回読み込み時にも一度実行(初期表示で画面内にある要素を表示)
  onScroll();
});
getBoundingClientRectによる画面内判定の仕組み図解キャプチャ
▲ 画面内判定の仕組み(要素の上端 rect.top がブラウザ画面の高さ window.innerHeight より小さくなった瞬間に進入と判定)

処理の流れと判定ロジック

  • getBoundingClientRect():ブラウザの表示領域(ビューポートの最上端)を「0」としたときの、要素の現在の相対位置を返します。
  • rect.top < window.innerHeight:要素の上端の座標(rect.top)が、ブラウザ画面の高さ(window.innerHeight)より小さくなったとき、要素が画面の下端ラインを越えて画面内に入ったことを意味します。
  • onScroll() の初期実行:ページを読み込んだ時点で既にファーストビュー(画面内)にある要素に対しても、即座にアニメーションを適用するためにスクロールイベント登録直後にも呼び出しています。
ブラウザ開発者ツールでのクラス付与とCSS検証キャプチャ
▲ ブラウザの検証画面(DevTools)でスクロール時に「is-visible」が付与されスタイルが適用される様子

完成コード

HTMLファイル1つで手軽に動作確認ができるコード一式です。新規に「index.html」を作成して貼り付け、ブラウザで開くだけですぐにアニメーションを確認できます。

HTML / CSS / JS
index.html(完成コード)
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>スクロールフェードインのデモ</title>
  <style>
    /* ページ全体の余白とスクロール領域確保 */
    body {
      font-family: sans-serif;
      padding: 40px 20px;
      min-height: 200vh; /* スクロールできるよう高さを確保 */
    }

    /* フェードイン要素のスタイル */
    .fade-in-element {
      max-width: 600px;
      margin: 100px auto;
      padding: 30px;
      background-color: #ffffff;
      border: 1px solid #e2e8f0;
      border-radius: 8px;
      box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);

      /* アニメーションの初期状態 */
      opacity: 0;
      transform: translateY(20px);
      transition: opacity 0.5s ease-out, transform 0.5s ease-out;
    }

    /* 画面内に入ったときの状態 */
    .fade-in-element.is-visible {
      opacity: 1;
      transform: translateY(0);
    }
  </style>
</head>
<body>

  <h1>スクロールフェードインの動作確認</h1>
  <p>下にスクロールすると、要素が下からふわっと現れます。</p>

  <div class="fade-in-element">
    <h2>コンテンツカード 1</h2>
    <p>画面内に入ると、滑らかに表示されます。</p>
  </div>

  <div class="fade-in-element">
    <h2>コンテンツカード 2</h2>
    <p>複数の要素にも同じクラス名で対応できます。</p>
  </div>

  <script>
    document.addEventListener('DOMContentLoaded', () => {
      const elements = document.querySelectorAll('.fade-in-element');

      const onScroll = () => {
        elements.forEach(element => {
          const rect = element.getBoundingClientRect();
          if (rect.top < window.innerHeight) {
            element.classList.add('is-visible');
          }
        });
      };

      window.addEventListener('scroll', onScroll);
      onScroll();
    });
  </script>
</body>
</html>

より自然に見せる調整テクニック

実際のWebサイトデザインに合わせて、さらに心地よい表示タイミングにカスタマイズしたい場合は、判定位置のオフセット調整が効果的です。

画面の少し奥に入ってから表示させたい場合

要素が画面の端ギリギリではなく、50px〜100pxほど画面の内側に入ってから表示させたい場合は、判定式から数値を引きます。

// 画面下端からさらに80px入ったタイミングで表示
if (rect.top < window.innerHeight - 80) {
  element.classList.add('is-visible');
}

まとめ

JavaScriptとCSSを組み合わせることで、jQueryや重いアニメーションライブラリを使わなくても、軽量で滑らかなフェードインアニメーションを実装できます。

  • CSSの「opacity」と「transform: translateY」で移動と透明度を制御
  • 「transition: 0.5s ease-out」で滑らかな減速アニメーションを演出
  • JavaScriptの「getBoundingClientRect()」で画面内進入を正確に判定

ブログ記事の見出しやカード一覧、お問い合わせボタンなど、注目を集めたいコンテンツにぜひ取り入れてみてください。


eguchi.netをもっと見る

購読すると最新の投稿がメールで送信されます。