<div class="container">
<div class="box js-scrollIn"></div>
<div class="box js-scrollIn"></div>
<div class="box js-scrollIn"></div>
<div class="box js-scrollIn"></div>
<div class="box js-scrollIn"></div>
<div class="box js-scrollIn"></div>
<div class="box js-scrollIn"></div>
<div class="box js-scrollIn"></div>
</div>
@charset "UTF-8";
.container {
padding: 40px 0;
}
.box {
width: 80%;
max-width: 600px;
margin: 0 auto;
background-color: #ddd;
aspect-ratio: 5 / 2;
+ .box {
margin-top: 8rem;
}
}
.js-scrollIn {
transform: translateY(30px);
opacity: 0;
transition: all 0.8s ease;
}
.js-scrollIn.active {
transform: translateY(0);
opacity: 1;
}
View Compiled
// DOMの読み込みが完了したらhandleScrollIn関数を実行
document.addEventListener("DOMContentLoaded", () => {
handleScrollIn();
});
// スクロールアニメーションを処理する関数
const handleScrollIn = () => {
// .js-scrollInクラスを持つ全ての要素を取得
const targets = document.querySelectorAll(".js-scrollIn");
// Intersection Observerのオプションを設定
const options = {
root: null, // ビューポート全体を監視対象とする
rootMargin: "-20% 0px", // 上下20%のマージンを設定(要素が20%見えたら発火)
threshold: [0] // 交差が始まった時点でコールバックを実行
};
// 交差時に実行されるコールバック関数
const callback = (entries, observer) => {
entries.forEach((entry) => {
// 要素が交差したら
if (entry.isIntersecting) {
// activeクラスを追加してアニメーションを開始
entry.target.classList.add("active");
// 一度アニメーションが開始したら、その要素の監視を終了
observer.unobserve(entry.target);
}
});
};
// Intersection Observerインスタンスを作成
const observer = new IntersectionObserver(callback, options);
// 全てのターゲット要素に対してIntersection Observerを設定
targets.forEach((target) => {
observer.observe(target);
});
};
This Pen doesn't use any external JavaScript resources.