3Dカードフリップ遷移
CSS 3D Transforms の preserve-3d と backface-visibility で表裏をY軸回転。クリックやキー操作でめくれるプロフィールカードの立体トランジションです。
ライブデモ
使用例(お題: アイドルグループ 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で提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。