【5分で実装】スクロールするとコンテンツが出現4選 💡
👇️ スクロールしてみてください 👇️
A:シンプルなフェードイン要素
See the Pen A:シンプルなフェードイン要素 by N Katsumata (@nk-codepen) on CodePen.
コードを見る
HTML
<div class="fade-in">
A:シンプルなフェードイン要素
</div>
CSS
.fade-in {
opacity: 0;
transition: opacity 1.2s ease-in-out;
}
.fade-in.is-visible {
opacity: 1;
}
JavaScript(Vanilla JS)
const fadeInTargets = document.querySelectorAll(".fade-in");
const fadeInObserver = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add("is-visible");
observer.unobserve(entry.target);
}
});
});
fadeInTargets.forEach((target) => {
fadeInObserver.observe(target);
});
💡 ワンポイント解説:
「class=”fade-in”」をつけたセクションすべてがフェードインするようになります。また、transition: 1.2s; の数字を大きくするとゆっくり、小さくすると素早くなります。
B:ふわっと浮かび上がる要素
See the Pen B:ふわっと浮かび上がる要素 by N Katsumata (@nk-codepen) on CodePen.
コードを見る
HTML
<div class="fade-in-up">
B:ふわっと浮かび上がる要素
</div>
CSS
.fade-in-up {
opacity: 0;
transform: translateY(20px);
transition: opacity 0.8s ease-out, transform 0.8s ease-out;
}
.fade-in-up.is-visible {
opacity: 1;
transform: translateY(0);
}
JavaScript(Vanilla JS)
const fadeInUpTargets = document.querySelectorAll(".fade-in-up");
const fadeInUpObserver = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add("is-visible");
observer.unobserve(entry.target);
}
});
});
fadeInUpTargets.forEach((target) => {
fadeInUpObserver.observe(target);
});
💡 ワンポイント解説:
このアニメーションを実装する際は下に余白を追加してください。特にセクション前後に余白があるデザインに向いています。また、transform: translateY(20px); の数字を大きくすると、より下から大きく浮かび上がります。
C:左からスライドイン
See the Pen C:左からスライドイン by N Katsumata (@nk-codepen) on CodePen.
コードを見る
HTML
<div class="slide-in-left">
C:左からスライドイン
</div>
CSS
.slide-in-left {
opacity: 0;
transition: opacity 0.8s ease-out, transform 0.8s ease-out;
}
.slide-in-left {
transform: translateX(-50px);
}
.slide-in-left.is-visible {
opacity: 1;
transform: translateX(0);
}
JavaScript(Vanilla JS)
const slideInLeftTargets = document.querySelectorAll(".slide-in-left");
const slideInLeftObserver = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add("is-visible");
observer.unobserve(entry.target);
}
});
});
slideInLeftTargets.forEach((target) => {
slideInLeftObserver.observe(target);
});
D:右からスライドイン
See the Pen Untitled by N Katsumata (@nk-codepen) on CodePen.
コードを見る
HTML
<div class="slide-in-right">
D:右からスライドイン
</div>
CSS
.slide-in-right {
opacity: 0;
transition: opacity 0.8s ease-out, transform 0.8s ease-out;
}
.slide-in-right {
transform: translateX(50px);
}
.slide-in-right.is-visible {
opacity: 1;
transform: translateX(0);
}
JavaScript(Vanilla JS)
const slideInRightTargets = document.querySelectorAll(".slide-in-right");
const slideInRightObserver = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add("is-visible");
observer.unobserve(entry.target);
}
});
});
slideInRightTargets.forEach((target) => {
slideInRightObserver.observe(target);
});
【ステップアップ】自分好みにカスタマイズしよう💡
コピペしたそのままでも使えますが、ほんの少し数字を変えるだけで、サイトの印象をガラッと変えることができます。
1. 速度と距離の変え方
CSSの中にある「0.8s」や「30px」といった数字に注目してみましょう。
- 表示スピードを変えたい
CSSの transition: 1.0s; の部分を変更します。- 0.8s にすると:キビキビとした、軽快でモダンな印象
- 2.0s にすると:高級感のある、ゆったりとした優雅な印象
- 動く距離を変えたい
CSSの transform: translateY(50px); の数字を変更します。- 30px にすると:さりげなく、品の良い動き
- 100px にすると:ダイナミックで、インパクトの強い動き
2. 時間差(ディレイ)でオシャレに見せるコツ
See the Pen 時間差(ディレイ)でオシャレに見せるコツ by N Katsumata (@nk-codepen) on CodePen.
複数のカードが並んでいる時、全部一緒に「パッ」と出るよりも、左から順に「ト・ト・トッ」と時差で出てくるとプロっぽく見えます。
これはJavaScriptをいじらなくても、HTMLに1行追加するだけでOKです!
<!-- 1つ目はそのまま -->
<div class="fade-in-up">内容1</div>
<!-- 2つ目は0.2秒遅らせる -->
<div class="fade-in-up" style="transition-delay: 0.2s;">内容2</div>
<!-- 3つ目は0.4秒遅らせる -->
<div class="fade-in-up" style="transition-delay: 0.4s;">内容3</div>
このように style=”transition-delay: 〇s;” を足すだけで、リズム感のあるサイトになりますよ♪
3つ以上の場合はCSSにしよう!
/* 共通の動きはそのまま */
.fade-in-up {
transition: transform 0.6s ease-out, opacity 0.6s ease-out;
}
/* 2番目から0.2秒ずつ加算 */
.fade-in-up:nth-child(2) { transition-delay: 0.2s; }
.fade-in-up:nth-child(3) { transition-delay: 0.4s; }
.fade-in-up:nth-child(4) { transition-delay: 0.6s; }
.fade-in-up:nth-child(5) { transition-delay: 0.8s; }
.fade-in-up:nth-child(6) { transition-delay: 1.0s; }
【Q&A】よくあるトラブルと解決策 🛠️
「コードを貼ったのに動かない!」という時に確認してほしいポイントをまとめました。
- Qコードを貼ったのに全く動きません…
- A
まずは「クラス名」と「JSの読み込み」をチェック!
- スペルミスはありませんか?
HTMLに書いたクラス名(例:fade-in-up)と、CSSのクラス名が1文字でも違うと動きません。 - JavaScriptは正しく読み込まれていますか?
今回のコードは必ず </body> タグの直前か、記事冒頭で説明した DOMContentLoaded の中に書くようにしてください。
- スペルミスはありませんか?
- Qスマホで見ると動きが変、またはカクつきます
- A
移動距離が大きすぎるかもしれません。
PCでは綺麗に見えても、画面の小さいスマホでは「左からスライドイン」の距離が長すぎると、横揺れ(横スクロール)が発生する原因になります。
スマホでの表示が気になる場合は、移動距離(30pxなど)を少し小さめに設定するのがコツです。
- Q一度表示された後、スクロールで戻ると消えてしまいます
- A
今回のコードは「一度だけ実行」する設定にしています。
何度も繰り返し出したい場合は、JavaScript内の observer.unobserve(entry.target); という1行を削除してください。これで、スクロールするたびに何度でもアニメーションが実行されるようになります
【ポイント解説】ここだけは抑えておきたい!💡
JavaScriptのコードは『DOMContentLoaded』の中に書こう
Vanilla JS(素のJavaScript)を扱う上で、
document.addEventListener('DOMContentLoaded', () => {
// この中に処理を書く
});
という記述は、コードが予期せぬエラーで動かなくなるのを防ぐための非常に重要なおまじないだと考えてください。
では、なぜこれが必要なのでしょうか?
これには、ブラウザがHTMLファイルを上から一行ずつ読み込むことに理由があります。
もし、HTMLの要素(例:ボタン)が作られる前に、その要素を操作しようとするJavaScriptが実行されたらどうなるでしょうか?

おそらく「Cannot read properties of null (reading ‘addEventListener’)」などのエラーが出るでしょう。これは、「buttonがnull(=何も見つからない)なのに、addEventListenerを実行しようとしていますよ」という意味です。
ここで登場するのが『DOMContentLoaded』です。これは、「ページのHTML構造の準備がすべて完了したタイミングで、中の処理を実行してね」というブラウザへの命令になります。
このコードがあればHTMLの読み込みが終わるまでaddEventListenerの中の処理は待機してくれるのです。結果、ブラウザがボタンを認識し終わった完璧なタイミングで処理が実行されるため、エラーは発生しません。
そのため、今回ご紹介しているJavaScriptコードを使用する際は『DOMContentLoaded』の中に書いてくださいね。
document.addEventListener('DOMContentLoaded', () => {
// この中に処理を書く、いくつ書いてもOK!HTMLを読み込んだ後に処理してくれます。
});
各ご紹介コードに書いていないのは『document.addEventListener(‘DOMContentLoaded’, () => {~});』ごと何度も同じJSファイルに書き込んでしまうのを防ぐためです。

フェードイン/アップ、左右のスライド全部使いたいって時
下記JSのみをコピペしてください。HTMLとCSSはそのままでOK◎
const animationTargets = document.querySelectorAll(
'.fade-in, .fade-in-up, .slide-in-left, .slide-in-right'
);
const handleIntersect = (entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
observer.unobserve(entry.target);
}
});
};
const observer = new IntersectionObserver(handleIntersect);
animationTargets.forEach(target => {
observer.observe(target);
});
もしよろしければ、他のコピペシリーズもご覧くださいね 👇️







