要素が徐々に現れるフェードインは、シンプルで効果的な演出です。opacity を 0 から 1 へ変化させるだけで実現できます。
古い記事では setInterval で少しずつ opacity を動かしますが、カクついて非効率です。現代はCSSの transition やWeb Animations API(element.animate)で滑らかに書けます。スクロールで表示したい場合はIntersectionObserverでふわっと表示させる方法を参照してください。
transition: opacity を設定し、クラスを付けて opacity を 1 にするのが最短です。JavaScriptだけで完結させたいなら element.animate()(Web Animations API)。setInterval での手動アニメは古いので避け、prefers-reduced-motion への配慮も忘れずに。完成イメージ(動くデモ)
↓ ボタンを押すと、ふわっとフェードインします:
CSSのtransitionでフェードインする(最短)
もっとも手軽で滑らかなのが、CSSの transition を使う方法です。初期状態を opacity: 0 にしておき、クラスを付けて opacity: 1 に変えるだけでブラウザが滑らかにアニメーションします。
<div id="target" class="fade-in">こんにちは、世界!</div>
.fade-in {
opacity: 0;
transition: opacity 1s ease; /* 1秒かけて変化 */
}
.fade-in.is-visible {
opacity: 1;
}
const el = document.getElementById("target");
window.addEventListener("DOMContentLoaded", () => {
el.classList.add("is-visible"); // クラスを付けるだけでフェードイン
});
Web Animations API(element.animate)でフェードインする
CSSを書かずにJavaScriptだけで完結させたいときは、Web Animations API の element.animate() が便利です。キーフレームと時間を指定するだけで滑らかにアニメーションします。
const el = document.getElementById("target");
el.animate(
[{ opacity: 0 }, { opacity: 1 }], // 0 → 1
{ duration: 1000, easing: "ease", fill: "forwards" } // 1秒・終了状態を保持
);
fill: "forwards" を付けると、アニメーション終了後も最後の状態(表示)を保ちます。setInterval による手動アニメと違い、ブラウザが最適化してくれるので滑らかです。
prefers-reduced-motionで配慮する
OSで「視差効果を減らす」を設定しているユーザーのために、prefers-reduced-motion でアニメーションを抑える配慮を入れましょう。
@media (prefers-reduced-motion: reduce) {
.fade-in {
transition: none;
opacity: 1; /* アニメーションせず最初から表示 */
}
}
setIntervalの手動アニメは避ける
setInterval(() => { opacity += 0.05; ... }, 50) のようにopacity を少しずつ動かす方法は、50ms刻み(約20fps)でカクつき、タブが非アクティブだとずれるなど効率も良くありません。CSSの transition か element.animate() を使えば、ブラウザが滑らかに(フレームに同期して)描画してくれます。スクロール表示・横スライドにしたい場合
フェードインの「きっかけ」を変えたい場合は、次の記事も参考になります。
- スクロールして画面に入ったらフェードイン → IntersectionObserverでふわっと表示させる方法
- 横からスライドさせながらフェードイン → 画面の横からフェードインさせる方法
- 画像を回転させ続けるなどのCSSアニメ → 画像を回転させ続ける方法
よくある質問(FAQ)
transition: opacity を設定し、JavaScriptで element.classList.add("is-visible") のようにクラスを付けて opacity を 1 にするのが最短です。JSだけなら element.animate([{opacity:0},{opacity:1}], {duration:1000, fill:"forwards"}) も使えます。mouseenter / mouseleave でクラスを切り替えるか、CSSの :hover と transition を使います。ホバーだけならCSSのみの方がシンプルです。IntersectionObserver を使い、要素が画面に入ったときにクラスを追加してopacity や transform のアニメーションをトリガーします。詳しくはIntersectionObserverでふわっと表示させる方法を参照してください。IntersectionObserver なら、クラスを付けた直後に observer.unobserve(element) で監視を停止します。読み込み時のフェードインなら、一度だけクラスを付ければ再生されません。まとめ
要素のフェードインは、CSSの transition: opacity + クラス付与がもっとも手軽で滑らかです。JavaScriptだけで完結させたいなら element.animate()(Web Animations API)を使います。
setInterval で opacity を手動アニメする方法は古く、カクつくので避けましょう。prefers-reduced-motion への配慮も加えると親切です。スクロールや横スライドなど「きっかけ」を変えたい場合は、関連記事を参考にしてください。
