Intersection Observerでスクロール時にフェードインさせる方法
'26.11.05Intersection Observer APIを使用し、スクロールによって要素が画面内に入ったタイミングでCSSアニメーションを実行。
スクロールイベントを常時監視する必要がなく、jQueryも不要。
HTML
アニメーションさせたい要素にinview-upクラスを追加。
<div class="inview-up">
<p>スクロールでフェードインする要素</p>
</div>CSS
通常時は要素を表示。JavaScriptで監視が開始された要素だけ、透明度と位置を変更。
挿入場所:テーマのCSSファイル
/* スクロールフェードイン */.inview-up {
opacity: 1;
transform: translateY(0);
transition: opacity .6s ease, transform .6s ease;
}
.inview-up.is-pending {
opacity: 0;
transform: translateY(30px);
}
.inview-up.is-visible {
opacity: 1;
transform: translateY(0);
}
/* アニメーション軽減設定 */@media (prefers-reduced-motion: reduce) {
.inview-up {
transition: none;
transform: none;
}
}JavaScript
挿入場所:テーマのJavaScriptファイル(DOM読み込み後に実行)
document.addEventListener('DOMContentLoaded', function () {
const targets = document.querySelectorAll('.inview-up');
if (!targets.length) return;
if (!('IntersectionObserver' in window)) return;
targets.forEach(el => el.classList.add('is-pending'));
const observer = new IntersectionObserver(function (entries) {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
entry.target.classList.remove('is-pending');
observer.unobserve(entry.target);
}
});
}, {
root: null,
rootMargin: '0px 0px -50px 0px',
threshold: 0
});
targets.forEach(el => observer.observe(el));
});オプション設定
root
監視の基準となる要素を指定。nullでブラウザの表示領域を使用。
rootMargin
監視領域の範囲を調整。
rootMargin: '0px 0px -50px 0px'
表示領域の下端を50px縮小。要素がその範囲に入ったタイミングで実行。
threshold
要素の表示割合を指定。
threshold: 0.5
要素の約50%が監視領域内に入ったタイミングで判定。
ただし、初期状態ですでに条件を満たしている場合も実行される。
アニメーション速度の変更
CSSのtransitionで速度を変更。
.inview-up {
transition: opacity 1s ease, transform 1s ease;
}.6sを1sに変更すると、アニメーションがゆっくりになる。
一度だけ実行する
表示後に監視を解除する場合はunobserve()を使用。
observer.unobserve(entry.target);
上記の基本コードでは実装済み。再スクロール時にアニメーションを繰り返さない。
注意点
- JavaScriptを読み込めない場合も、要素は通常表示される。
- ページ表示時から画面内にある要素は、初期判定でアニメーションが実行される。
thresholdを大きくすると、高さのある要素では条件を満たせない場合がある。prefers-reduced-motionにより、アニメーション軽減設定に対応。- アニメーションさせたい要素に
inview-upを追加するだけで使用可能。
(View:5)