3Dカードフリップ遷移

CSS 3D Transforms の preserve-3d と backface-visibility で表裏をY軸回転。クリックやキー操作でめくれるプロフィールカードの立体トランジションです。

#css#3d#transform#interaction

ライブデモ

使用例(お題: アイドルグループ Sakura)

この技法を「アイドルグループ Sakura」というテーマのダミーサイトで実際に使った例です。

HTML
<!-- Sakura: メンバーのトレーディングカード。3Dフリップで表⇔プロフィール裏面 -->
<div class="kf-stage">
  <div class="kf-head">
    <span class="kf-brand">🌸 Sakura</span>
    <span class="kf-sub">MEMBER CARD</span>
  </div>

  <div class="kf-scene">
    <div class="kf-card" tabindex="0" role="button" aria-pressed="false" aria-label="カードをめくる">
      <!-- 表面 -->
      <div class="kf-face kf-face--front">
        <span class="kf-no">No.01</span>
        <span class="kf-orb"></span>
        <span class="kf-photo"></span>
        <h2 class="kf-name">星野 ひなた</h2>
        <p class="kf-color">桜色担当 / センター</p>
        <span class="kf-hint">クリック / Enter でめくる ↺</span>
      </div>
      <!-- 裏面 -->
      <div class="kf-face kf-face--back">
        <h3 class="kf-back-title">PROFILE</h3>
        <ul class="kf-list">
          <li><span>誕生日</span><b>4月3日</b></li>
          <li><span>出身</span><b>東京都</b></li>
          <li><span>好きな食べ物</span><b>いちご大福</b></li>
          <li><span>特技</span><b>クラシックバレエ</b></li>
        </ul>
        <span class="kf-hint">もう一度で表へ ↻</span>
      </div>
    </div>
  </div>
</div>
CSS
* { box-sizing: border-box; }

:root {
  --ease: cubic-bezier(.6, .04, .2, 1);
  --radius: 18px;
}

body {
  margin: 0;
  min-height: 400px;
  display: grid;
  place-items: center;
  font-family: "Hiragino Kaku Gothic ProN", "Segoe UI", system-ui, sans-serif;
  color: #4a3540;
  background:
    radial-gradient(560px 300px at 50% -10%, #ffe7f0 0%, transparent 60%),
    #fff6fa;
}

.kf-stage { display: grid; place-items: center; gap: 16px; }

.kf-head { display: flex; align-items: baseline; gap: 12px; }
.kf-brand { font-size: 17px; font-weight: 800; color: #ff6fa3; }
.kf-sub { font-size: 11px; letter-spacing: .3em; color: #c79ab0; font-weight: 700; }

.kf-scene { perspective: 1200px; }

.kf-card {
  position: relative;
  width: 270px;
  height: 220px;
  transform-style: preserve-3d;
  transition: transform .7s var(--ease);
  cursor: pointer;
  border-radius: var(--radius);
  outline: none;
}
.kf-card.is-flipped { transform: rotateY(180deg); }
.kf-card:focus-visible { box-shadow: 0 0 0 3px #ff8fb3; }

.kf-face {
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
  padding: 20px;
  backface-visibility: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 18px 40px rgba(255, 130, 175, .35);
  overflow: hidden;
}

/* 表面 */
.kf-face--front {
  background: linear-gradient(155deg, #ffd1e0 0%, #ff9ec2 55%, #ff6fa3 100%);
  color: #5a2f44;
}
.kf-no { font-size: 11px; letter-spacing: .25em; font-weight: 800; opacity: .85; }
.kf-orb {
  position: absolute;
  top: -36px; right: -28px;
  width: 120px; height: 120px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, rgba(255,255,255,.8), rgba(255,255,255,0) 65%);
}
.kf-photo {
  position: absolute;
  top: 16px; right: 16px;
  width: 56px; height: 56px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 35%, rgba(255,255,255,.7) 0 18%, transparent 20%),
    linear-gradient(150deg, #fff0f6, #ff8fb3);
  border: 2px solid rgba(255, 255, 255, .7);
}
.kf-name { margin: auto 0 4px; font-size: 26px; letter-spacing: .02em; }
.kf-color { margin: 0 0 12px; font-size: 12px; opacity: .9; font-weight: 600; }

/* 裏面(初期に180度回しておく) */
.kf-face--back {
  background: linear-gradient(155deg, #fff 0%, #fff0f6 100%);
  transform: rotateY(180deg);
  border: 1px solid #ffd6e4;
}
.kf-back-title { margin: 0 0 12px; font-size: 14px; letter-spacing: .25em; color: #ff6fa3; }
.kf-list { list-style: none; margin: 0 0 auto; padding: 0; }
.kf-list li {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  padding: 6px 0;
  border-bottom: 1px solid #ffe0ea;
}
.kf-list li span { color: #b08a9a; }
.kf-list li b { color: #5a3545; font-weight: 700; }

.kf-hint { font-size: 11px; opacity: .8; }
.kf-face--front .kf-hint { color: #6e3a50; }
.kf-face--back .kf-hint { color: #c79ab0; }

@media (prefers-reduced-motion: reduce) {
  .kf-card { transition-duration: 1ms; }
}
JavaScript
// Sakura メンバーカード: クリック/キーで表裏を3Dフリップ(状態はクラスで管理)
(() => {
  const card = document.querySelector('.kf-card');
  if (!card) return; // null安全

  const flip = () => {
    const flipped = card.classList.toggle('is-flipped');
    card.setAttribute('aria-pressed', String(flipped));
  };

  card.addEventListener('click', flip);

  // Enter / Space でも反転(ボタン相当のキー操作)
  card.addEventListener('keydown', (e) => {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      flip();
    }
  });
})();

コード

HTML
<!-- 3Dカードフリップ: 表/裏をY軸回転で切替える立体遷移 -->
<div class="cf-stage">
  <div class="cf-scene">
    <div class="cf-card" tabindex="0" role="button" aria-pressed="false" aria-label="カードをめくる">
      <!-- 表面 -->
      <div class="cf-face cf-face--front">
        <span class="cf-tag">MEMBER</span>
        <span class="cf-orb"></span>
        <h2 class="cf-name">AURORA</h2>
        <p class="cf-role">Front-end Designer</p>
        <span class="cf-hint">クリック / Enter で反転 ↺</span>
      </div>
      <!-- 裏面 -->
      <div class="cf-face cf-face--back">
        <h3 class="cf-back-title">Profile</h3>
        <ul class="cf-list">
          <li>✦ CSS 3D Transforms</li>
          <li>✦ Web Animations API</li>
          <li>✦ View Transitions</li>
        </ul>
        <span class="cf-hint">もう一度で表へ ↻</span>
      </div>
    </div>
  </div>
</div>
CSS
* { box-sizing: border-box; }

:root {
  --ease: cubic-bezier(.6, .04, .2, 1);
  --radius: 18px;
}

body {
  margin: 0;
  min-height: 360px;
  display: grid;
  place-items: center;
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  color: #fff;
  background:
    radial-gradient(600px 300px at 50% -10%, #2a2f55 0%, transparent 60%),
    #0a0b14;
}

.cf-stage { width: min(620px, 92vw); display: grid; place-items: center; }

/* 遠近感を親に付与 */
.cf-scene { perspective: 1200px; }

.cf-card {
  position: relative;
  width: 280px;
  height: 200px;
  transform-style: preserve-3d;
  transition: transform .7s var(--ease);
  cursor: pointer;
  border-radius: var(--radius);
  outline: none;
}
.cf-card.is-flipped { transform: rotateY(180deg); }
.cf-card:focus-visible { box-shadow: 0 0 0 3px #7c9cff; }

.cf-face {
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
  padding: 22px;
  backface-visibility: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 20px 45px rgba(0,0,0,.5);
  overflow: hidden;
}

/* 表面 */
.cf-face--front {
  background: linear-gradient(150deg, #6a5cff 0%, #b14cff 55%, #ff5ca0 100%);
}
.cf-tag {
  font-size: 11px;
  letter-spacing: .3em;
  font-weight: 700;
  opacity: .9;
}
.cf-orb {
  position: absolute;
  top: -40px; right: -30px;
  width: 130px; height: 130px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, rgba(255,255,255,.7), rgba(255,255,255,0) 65%);
}
.cf-name { margin: auto 0 4px; font-size: 32px; letter-spacing: .04em; }
.cf-role { margin: 0 0 14px; font-size: 13px; opacity: .9; }

/* 裏面(初期に180度回しておく) */
.cf-face--back {
  background: linear-gradient(150deg, #11131f 0%, #1c2138 100%);
  transform: rotateY(180deg);
  border: 1px solid rgba(255,255,255,.08);
}
.cf-back-title { margin: 0 0 14px; font-size: 18px; }
.cf-list { list-style: none; margin: 0 0 auto; padding: 0; }
.cf-list li {
  font-size: 14px;
  padding: 7px 0;
  border-bottom: 1px solid rgba(255,255,255,.08);
  color: #c8cde6;
}

.cf-hint { font-size: 11px; opacity: .8; }

@media (prefers-reduced-motion: reduce) {
  .cf-card { transition-duration: 1ms; }
}
JavaScript
// 3Dカードフリップ: クリック/キーで表裏を反転(状態はクラスで管理)
(() => {
  const card = document.querySelector('.cf-card');
  if (!card) return; // null安全

  const flip = () => {
    const flipped = card.classList.toggle('is-flipped');
    card.setAttribute('aria-pressed', String(flipped));
  };

  card.addEventListener('click', flip);

  // Enter / Space でも反転(ボタン相当のキー操作)
  card.addEventListener('keydown', (e) => {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      flip();
    }
  });
})();

🤖 AIエージェント用プロンプト

このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「3Dカードフリップ遷移」の効果を追加してください。

# 追加してほしい効果
3Dカードフリップ遷移(ページ遷移 / View Transitions)
CSS 3D Transforms の preserve-3d と backface-visibility で表裏をY軸回転。クリックやキー操作でめくれるプロフィールカードの立体トランジションです。

# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】

# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- 3Dカードフリップ: 表/裏をY軸回転で切替える立体遷移 -->
<div class="cf-stage">
  <div class="cf-scene">
    <div class="cf-card" tabindex="0" role="button" aria-pressed="false" aria-label="カードをめくる">
      <!-- 表面 -->
      <div class="cf-face cf-face--front">
        <span class="cf-tag">MEMBER</span>
        <span class="cf-orb"></span>
        <h2 class="cf-name">AURORA</h2>
        <p class="cf-role">Front-end Designer</p>
        <span class="cf-hint">クリック / Enter で反転 ↺</span>
      </div>
      <!-- 裏面 -->
      <div class="cf-face cf-face--back">
        <h3 class="cf-back-title">Profile</h3>
        <ul class="cf-list">
          <li>✦ CSS 3D Transforms</li>
          <li>✦ Web Animations API</li>
          <li>✦ View Transitions</li>
        </ul>
        <span class="cf-hint">もう一度で表へ ↻</span>
      </div>
    </div>
  </div>
</div>

【CSS】
* { box-sizing: border-box; }

:root {
  --ease: cubic-bezier(.6, .04, .2, 1);
  --radius: 18px;
}

body {
  margin: 0;
  min-height: 360px;
  display: grid;
  place-items: center;
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  color: #fff;
  background:
    radial-gradient(600px 300px at 50% -10%, #2a2f55 0%, transparent 60%),
    #0a0b14;
}

.cf-stage { width: min(620px, 92vw); display: grid; place-items: center; }

/* 遠近感を親に付与 */
.cf-scene { perspective: 1200px; }

.cf-card {
  position: relative;
  width: 280px;
  height: 200px;
  transform-style: preserve-3d;
  transition: transform .7s var(--ease);
  cursor: pointer;
  border-radius: var(--radius);
  outline: none;
}
.cf-card.is-flipped { transform: rotateY(180deg); }
.cf-card:focus-visible { box-shadow: 0 0 0 3px #7c9cff; }

.cf-face {
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
  padding: 22px;
  backface-visibility: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 20px 45px rgba(0,0,0,.5);
  overflow: hidden;
}

/* 表面 */
.cf-face--front {
  background: linear-gradient(150deg, #6a5cff 0%, #b14cff 55%, #ff5ca0 100%);
}
.cf-tag {
  font-size: 11px;
  letter-spacing: .3em;
  font-weight: 700;
  opacity: .9;
}
.cf-orb {
  position: absolute;
  top: -40px; right: -30px;
  width: 130px; height: 130px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, rgba(255,255,255,.7), rgba(255,255,255,0) 65%);
}
.cf-name { margin: auto 0 4px; font-size: 32px; letter-spacing: .04em; }
.cf-role { margin: 0 0 14px; font-size: 13px; opacity: .9; }

/* 裏面(初期に180度回しておく) */
.cf-face--back {
  background: linear-gradient(150deg, #11131f 0%, #1c2138 100%);
  transform: rotateY(180deg);
  border: 1px solid rgba(255,255,255,.08);
}
.cf-back-title { margin: 0 0 14px; font-size: 18px; }
.cf-list { list-style: none; margin: 0 0 auto; padding: 0; }
.cf-list li {
  font-size: 14px;
  padding: 7px 0;
  border-bottom: 1px solid rgba(255,255,255,.08);
  color: #c8cde6;
}

.cf-hint { font-size: 11px; opacity: .8; }

@media (prefers-reduced-motion: reduce) {
  .cf-card { transition-duration: 1ms; }
}

【JavaScript】
// 3Dカードフリップ: クリック/キーで表裏を反転(状態はクラスで管理)
(() => {
  const card = document.querySelector('.cf-card');
  if (!card) return; // null安全

  const flip = () => {
    const flipped = card.classList.toggle('is-flipped');
    card.setAttribute('aria-pressed', String(flipped));
  };

  card.addEventListener('click', flip);

  // Enter / Space でも反転(ボタン相当のキー操作)
  card.addEventListener('keydown', (e) => {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      flip();
    }
  });
})();

# 外部ライブラリ
なし(追加ライブラリ不要)

# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。