【完全版】IntersectionObserver×CSSアニメで実現!スクロール時に動く“下線アニメーション”の実装術

はじめに:下線アニメーションはもはや「UXの一部」

Webサイトでの見出し演出、あなたはどうしていますか?

最近のサイトでは、スクロールして表示されたときに下線がスッと引かれる演出がよく見られます。

ただのCSSだけでは難しそうに見えますが、**IntersectionObserver(インターセクションオブザーバー)**というモダンAPIを使えば、少ないコードで自然なアニメーションが実現できます。

この記事では、構造・CSS・JSすべてを解説しながら、再利用性の高い設計で下線アニメーションを作る方法を丁寧にご紹介します。


そもそもIntersectionObserverとは?

IntersectionObserverは、ある要素が**「画面に表示されたかどうか」を効率的に検出するブラウザのネイティブAPIです。

スクロールイベントのように毎フレーム処理を走らせないためパフォーマンスが高く、シンプルなコードで実装可能**です。


今回つくる演出のゴール

  • 対象要素(見出しなど)が画面内に50%以上表示されたタイミングで
  • アンダーライン(下線)が左から右に伸びていくように表示
  • 下線はCSSアニメーションで表現、JSは発火のトリガーだけを担当
  • 一度表示されたらアニメーションを維持(再スクロールでは再発火しない)

HTML構造:シンプルで再利用しやすく

<h2 class="scroll-underline">見出しタイトル</h2>
  • .scroll-underline はアニメーション対象クラスとして付与します
  • タグは <h2> に限らず <p> や <div> にも対応可能

CSS実装:下線アニメーションの設計

.scroll-underline {
  display: inline-block;
  position: relative;
  font-weight: bold;
  overflow: hidden;
}

.scroll-underline::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 3px;
  background-color: #007bff;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.5s ease-out;
}

.scroll-underline.is-visible::after {
  transform: scaleX(1);
}

💡ポイント解説:

  • ::afterで擬似要素の下線を作成
  • 初期状態はscaleX(0)で非表示
  • .is-visibleが付与された瞬間にscaleX(1)へ変化し、下線が伸びるように見える

JavaScript:IntersectionObserverで「表示されたか」を検出

document.addEventListener('DOMContentLoaded', () => {
  const elements = document.querySelectorAll('.scroll-underline');

  const observer = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        entry.target.classList.add('is-visible');
        observer.unobserve(entry.target); // 一度だけ表示でOKなら
      }
    });
  }, {
    threshold: 0.5 // 要素の50%が表示されたら発火
  });

  elements.forEach(el => observer.observe(el));
});

💡補足解説:

  • threshold: 0.5 → 要素の50%が表示されたときに発火
  • 一度だけ発火したいならobserver.unobserve()を使う
  • 複数要素が同時に登場してもOK!一覧ページやFAQなどにも有効

よくある拡張例

✅ 順番に下線を表示(ディレイ付き)

.scroll-underline:nth-child(1)::after { transition-delay: 0.1s; }
.scroll-underline:nth-child(2)::after { transition-delay: 0.2s; }
.scroll-underline:nth-child(3)::after { transition-delay: 0.3s; }
  • フェードインやリストなどと組み合わせてナチュラルな演出が可能

✅ セクションごとに色や太さを変える

.scroll-underline.type-primary::after { background: #007bff; height: 3px; }
.scroll-underline.type-warning::after { background: #ffc107; height: 2px; }
.scroll-underline.type-danger::after  { background: #dc3545; height: 4px; }
  • カラーの意味付けやデザイン表現の幅が広がる

ハマりがちな注意点とその回避法

課題解決方法
IntersectionObserverが効かないDOMContentLoadedを待つ、またはdeferを使ってJSを後ろで読み込む
スマホで発火が不安定thresholdを0.3〜0.5で調整すると安定しやすい
再スクロールで何度もアニメunobserve()で一度きりの発火に制御
アニメが途中で切れるoverflow: hiddenを親要素に追加し、描画を正しく保つ

応用アイデア:下線以外の応用にも使える!

IntersectionObserverは下線アニメーション以外にも活用可能です。

  • テキストや画像のフェードイン/ズームイン
  • カウントアップグラフ描画のトリガー
  • チャート、アコーディオン、Lottieアニメーションの起動条件に
  • もちろんLazy Load無限スクロールにも

まとめ:IntersectionObserverで“動きのあるUI”を軽く・賢く

項目内容
対象技術IntersectionObserver API + CSS transition
実装効果スクロールで自然に下線が引かれる視覚演出
対応ブラウザIE以外の主要ブラウザ(Polyfillで対応可)
学習コスト低〜中(再利用可能な汎用コードで構築可能)
おすすめ用途見出し/リスト/ブログ/LP/企業サイトなど

“スクロールで登場する動き”は、視線誘導やデザイン強調だけでなく、UXそのものにも影響を与えます。

IntersectionObserverは軽くて強力、かつ今後の実装の基本となる技術です。

(Visited 1 times, 1 visits today)