見せる・隠す(Show / Hide)

フェード・スライド・トグルアニメーションをFramer Motion / React Spring / GSAP / CSS Transitionで実装・比較

🔗 このページはFramer Motion / React Spring / GSAP / CSS Transitionを使ったReact実装です。バニラJSでの実装は要素の表示・非表示ページを参照してください。
Framer Motion

読み込み中...

tsx
'use client';
import { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';

export default function ShowHideFramerDemo() {
  const [visible, setVisible] = useState(true);

  return (
    <>
      <button onClick={() => setVisible(v => !v)}>トグル</button>

      {/* フェード */}
      <AnimatePresence>
        {visible && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.4 }}
          >
            フェードするコンテンツ
          </motion.div>
        )}
      </AnimatePresence>

      {/* スライドダウン */}
      <AnimatePresence>
        {visible && (
          <motion.div
            initial={{ opacity: 0, height: 0 }}
            animate={{ opacity: 1, height: 'auto' }}
            exit={{ opacity: 0, height: 0 }}
            transition={{ duration: 0.4, ease: 'easeInOut' }}
            style={{ overflow: 'hidden' }}
          >
            スライドするコンテンツ
          </motion.div>
        )}
      </AnimatePresence>

      {/* mode="wait" で切り替えアニメーション */}
      <AnimatePresence mode="wait">
        {visible ? (
          <motion.div
            key="shown"
            initial={{ opacity: 0, scale: 0.8 }}
            animate={{ opacity: 1, scale: 1 }}
            exit={{ opacity: 0, scale: 0.8 }}
            transition={{ duration: 0.3 }}
          >
            表示中
          </motion.div>
        ) : (
          <motion.div
            key="hidden"
            initial={{ opacity: 0, scale: 0.8 }}
            animate={{ opacity: 1, scale: 1 }}
            exit={{ opacity: 0, scale: 0.8 }}
            transition={{ duration: 0.3 }}
          >
            非表示
          </motion.div>
        )}
      </AnimatePresence>
    </>
  );
}

jQueryで書くとこうなる

jQueryでは .fadeIn().slideDown() などのメソッドで手軽にアニメーションを実装できました。Reactでは Framer Motion の AnimatePresence・React Spring の useTransition・GSAPの autoAlphatimeline() を使うことで、同等以上の表現が可能です。
js
// show / hide
$('#box').hide();
$('#box').show();

// toggle
$('#box').toggle();

// fadeIn / fadeOut
$('#box').fadeIn(400);
$('#box').fadeOut(400);

// fadeToggle
$('#box').fadeToggle(400);

// slideDown / slideUp
$('#box').slideDown(400);
$('#box').slideUp(400);

// slideToggle
$('#box').slideToggle(400);
💡 上記のデモは、React / Next.jsです。Next.jsの基本セットアップは 公式ドキュメントを参照してください。

実装方法の比較

項目Framer MotionReact SpringGSAPCSS Transition
DOMから削除AnimatePresenceでアンマウント時もアニメーション可能useTransitionでマウント・アンマウント時のアニメーションを制御autoAlphaでopacity+visibilityを同時制御(DOMに残る)DOMに残りopacityで隠す(アクセシビリティ注意)
高さアニメーションheight: 'auto' をアニメーション可能useSpringで数値指定(autoは不可。max-heightで代替)height: 'auto' をアニメーション可能(Framerと同等)max-heightで代替(厳密な高さ指定が必要)
切り替えアニメーションmode='wait'で前のアニメーション完了後に次を開始exitBeforeEnterで退場完了後に入場アニメーションを開始timeline()でtween をシーケンシャルに並べて実装同時遷移のみ(前後のアニメーション制御が困難)
設定コスト高:framer-motionのインストールが必要高:@react-spring/webのインストールが必要中:gsap + @gsap/reactのインストールが必要低:追加ライブラリ不要
パフォーマンスGPUアクセラレーション・60fps最適化済み物理ベース計算・GPUアクセラレーション対応高度に最適化・60fps保証・業界標準のパフォーマンスtransform/opacityはGPUアクセラレーション対象

AnimatePresence のポイント

  • AnimatePresence で囲むことで、コンポーネントのアンマウント時にも exit アニメーションが実行される
  • mode="wait" を指定すると、前のコンポーネントのexitアニメーション完了後に次のenterが始まる
  • height: 0 → 'auto' のアニメーションはFramer Motionでのみ可能(CSSではmax-heightで代替)
  • • CSS Transitionでは要素がDOMに残るため、スクリーンリーダーに読み上げられる可能性がある

🤖 AIプロンプトテンプレート

Next.js + Framer Motion で「見せる・隠す」アニメーションを実装してください。
- ボタンクリックで要素をフェードイン・フェードアウト
- ボタンクリックで要素をスライドダウン・スライドアップ
- AnimatePresence を使ってアンマウント時もアニメーションさせる
- TypeScript / Tailwind CSS v4 を使用

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

React Spring のポイント

  • useTransition でマウント・アンマウント時のアニメーションを制御できる(Framer の AnimatePresence に相当)
  • exitBeforeEnter: true で退場アニメーション完了後に入場が始まる(Framer の mode="wait" に相当)
  • useSpring の反応型(オブジェクト渡し)を使えば、stateの変化に応じてスムーズにアニメーションする
  • height: 'auto' のアニメーションは非対応。固定値か useResizeObserver を使う必要がある

🤖 AIプロンプトテンプレート

Next.js + React Spring で「見せる・隠す」アニメーションを実装してください。
- useTransition を使ってフェードイン・フェードアウト(DOMから削除)
- useSpring を使ってスライドダウン・スライドアップ(高さアニメーション)
- exitBeforeEnter で退場完了後に入場アニメーションを開始
- 使用ライブラリ: @react-spring/web
- TypeScript / Tailwind CSS v4 を使用

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

GSAP のポイント

  • useGSAP({ scope: container }) でスコープを限定し、コンポーネントのアンマウント時に自動でクリーンアップされる
  • contextSafe で包んだ関数内でのみ、クリーンアップ対象のアニメーションを安全に作成できる
  • autoAlphaopacityvisibility をまとめて制御する GSAP 専用プロパティ(opacity=0 のとき visibility=hidden になりスクリーンリーダー対応)
  • gsap.timeline() で複数のtweenをシーケンシャルに並べることで、退場→入場のような順序制御が直感的に書ける
  • • GSAP は height: 'auto' のアニメーションをネイティブにサポート(React Spring では非対応)

🤖 AIプロンプトテンプレート

Next.js + GSAP で「見せる・隠す」アニメーションを実装してください。
- useGSAP フックと contextSafe を使ってボタンクリックでアニメーションをトリガー
- autoAlpha でフェードイン・フェードアウト(opacity + visibility の同時制御)
- height: 'auto' をアニメーションしてスライドダウン・スライドアップ
- gsap.timeline() でシーケンシャルなトグル切り替えを実装
- 使用ライブラリ: gsap, @gsap/react
- TypeScript / Tailwind CSS v4 を使用

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

見せる・隠すアニメーション(Show / Hide)は、UI要素を表示・非表示するときに付与するトランジション効果。クリックなどのトリガーに連動する。

モーダルの開閉・ドロップダウンの展開・アコーディオンのパネル開閉・トースト通知の出現・消去など、UI状態の変化を滑らかに伝えたい場面で使われる。

主なバリエーション
  • フェードイン/アウト型
  • スライドイン/アウト型(上下・左右)
  • スケールアップ/ダウン型
  • ブラー型
  • 組み合わせ型(フェード+スライド)