【JavaScript】要素をふわっとフェードインさせる方法

要素が徐々に現れるフェードインは、シンプルで効果的な演出です。opacity を 0 から 1 へ変化させるだけで実現できます。

古い記事では setInterval で少しずつ opacity を動かしますが、カクついて非効率です。現代はCSSの transitionWeb Animations API(element.animateで滑らかに書けます。スクロールで表示したい場合はIntersectionObserverでふわっと表示させる方法を参照してください。

この記事の結論:フェードインはCSSで transition: opacity を設定し、クラスを付けて opacity を 1 にするのが最短です。JavaScriptだけで完結させたいなら element.animate()(Web Animations API)。setInterval での手動アニメは古いので避け、prefers-reduced-motion への配慮も忘れずに。
スポンサーリンク

完成イメージ(動くデモ)

↓ ボタンを押すと、ふわっとフェードインします:

ふわっと表示されます

CSSのtransitionでフェードインする(最短)

もっとも手軽で滑らかなのが、CSSの transition を使う方法です。初期状態を opacity: 0 にしておき、クラスを付けて opacity: 1 に変えるだけでブラウザが滑らかにアニメーションします。

HTML
<div id="target" class="fade-in">こんにちは、世界!</div>
CSS
.fade-in {
  opacity: 0;
  transition: opacity 1s ease; /* 1秒かけて変化 */
}
.fade-in.is-visible {
  opacity: 1;
}
JavaScript:読み込み後にフェードイン
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() が便利です。キーフレームと時間を指定するだけで滑らかにアニメーションします。

JavaScript: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 でアニメーションを抑える配慮を入れましょう。

CSS:動きを減らす設定では即表示
@media (prefers-reduced-motion: reduce) {
  .fade-in {
    transition: none;
    opacity: 1; /* アニメーションせず最初から表示 */
  }
}

setIntervalの手動アニメは避ける

古いやり方に注意:setInterval(() => { opacity += 0.05; ... }, 50) のようにopacity を少しずつ動かす方法は、50ms刻み(約20fps)でカクつき、タブが非アクティブだとずれるなど効率も良くありません。CSSの transitionelement.animate() を使えば、ブラウザが滑らかに(フレームに同期して)描画してくれます。

スクロール表示・横スライドにしたい場合

フェードインの「きっかけ」を変えたい場合は、次の記事も参考になります。

よくある質問(FAQ)

QJavaScriptで要素をフェードインさせる一番簡単な方法は?
ACSSで transition: opacity を設定し、JavaScriptで element.classList.add("is-visible") のようにクラスを付けて opacity を 1 にするのが最短です。JSだけなら element.animate([{opacity:0},{opacity:1}], {duration:1000, fill:"forwards"}) も使えます。
Qホバーしたときにフェードインするには?
Amouseenter / mouseleave でクラスを切り替えるか、CSSの :hovertransition を使います。ホバーだけならCSSのみの方がシンプルです。
Qスクロールで要素が見えたときにアニメーションするには?
AIntersectionObserver を使い、要素が画面に入ったときにクラスを追加してopacitytransform のアニメーションをトリガーします。詳しくはIntersectionObserverでふわっと表示させる方法を参照してください。
Q一度表示されたら再度アニメーションさせないようにするには?
AIntersectionObserver なら、クラスを付けた直後に observer.unobserve(element) で監視を停止します。読み込み時のフェードインなら、一度だけクラスを付ければ再生されません。

まとめ

要素のフェードインは、CSSの transition: opacity + クラス付与がもっとも手軽で滑らかです。JavaScriptだけで完結させたいなら element.animate()(Web Animations API)を使います。

setIntervalopacity を手動アニメする方法は古く、カクつくので避けましょう。prefers-reduced-motion への配慮も加えると親切です。スクロールや横スライドなど「きっかけ」を変えたい場合は、関連記事を参考にしてください。