カードフリップ デザイン見本
perspective と rotateY / rotateX を組み合わせた 3D カード反転の実装デモ。コピーしてすぐに使える HTML・CSS・JS のコードを掲載。
① ホバーでフリップ(CSSのみ)
HOVER ME
Back Side
hover を外すと戻ります
カードにホバーしてください
<div class="card-wrapper">
<div class="card">
<div class="front">
<p>HOVER ME</p>
</div>
<div class="back">
<p>Back Side</p>
</div>
</div>
</div>
.card-wrapper {
perspective: 800px;
width: 180px;
height: 240px;
}
.card {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
transition: transform 0.6s ease;
}
.card-wrapper:hover .card {
transform: rotateY(180deg);
}
.front,
.back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 12px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
padding: 20px;
box-sizing: border-box;
}
.front {
background: linear-gradient(135deg, #667eea, #764ba2);
color: #fff;
}
.back {
transform: rotateY(180deg);
background: #fff;
color: #333;
border: 2px solid #e2e8f0;
}
親要素に perspective を設定して 3D 空間の奥行感を生み出す。カード本体に transform-style: preserve-3d を付けると子要素も 3D 空間に配置される。裏面には rotateY(180deg) を初期値として付けておき、backface-visibility: hidden で裏側を透明にすることで自然な反転が実現できる。
② クリックでフリップ(JS 制御)
現在: 表面
CLICK ME
Back Side
もう一度クリックで戻る
<div class="card-wrapper">
<div class="card">
<div class="front">
<p>CLICK ME</p>
</div>
<div class="back">
<p>Back Side</p>
</div>
</div>
</div>
<button class="flip-btn">フリップ</button>
.card-wrapper {
perspective: 800px;
width: 180px;
height: 240px;
}
.card {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
transition: transform 0.6s ease;
}
.card.flipped {
transform: rotateY(180deg);
}
.front,
.back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 12px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
padding: 20px;
box-sizing: border-box;
}
.front {
background: linear-gradient(135deg, #06b6d4, #0891b2);
color: #fff;
}
.back {
transform: rotateY(180deg);
background: #f0fdfa;
color: #164e63;
border: 2px solid #a5f3fc;
}
.flip-btn {
margin-top: 16px;
padding: 8px 24px;
border-radius: 20px;
border: 1px solid #06b6d4;
background: #ecfeff;
color: #0e7490;
font-weight: 600;
cursor: pointer;
}
(function() {
var card = document.querySelector('.card');
var btn = document.querySelector('.flip-btn');
if (!card || !btn) return;
btn.addEventListener('click', function() {
var flipped = card.className.indexOf('flipped') !== -1;
if (flipped) {
card.className = 'card';
} else {
card.className = 'card flipped';
}
});
})();
CSS で .card.flipped { transform: rotateY(180deg); } を定義しておき、JS ではクラスを付け外しするだけでフリップを制御できる。className.indexOf(‘flipped’) で現在の状態を判定し、あれば外す・なければ付けるというシンプルなトグルで実装できる。
③ 縦方向フリップ(rotateX)
現在: 表面
CLICK ME
Back Side
rotateX で縦転する
<div class="card-wrapper">
<div class="card">
<div class="front">
<p>CLICK ME</p>
</div>
<div class="back">
<p>Back Side</p>
</div>
</div>
</div>
<button class="flip-btn">フリップ</button>
.card-wrapper {
perspective: 800px;
width: 180px;
height: 240px;
}
.card {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
transition: transform 0.6s ease;
}
.card.flipped {
transform: rotateX(180deg);
}
.front,
.back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 12px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
padding: 20px;
box-sizing: border-box;
}
.front {
background: linear-gradient(135deg, #f59e0b, #d97706);
color: #fff;
}
.back {
transform: rotateX(180deg);
background: #fffbeb;
color: #78350f;
border: 2px solid #fde68a;
}
.flip-btn {
margin-top: 16px;
padding: 8px 24px;
border-radius: 20px;
border: 1px solid #f59e0b;
background: #fffbeb;
color: #92400e;
font-weight: 600;
cursor: pointer;
}
(function() {
var card = document.querySelector('.card');
var btn = document.querySelector('.flip-btn');
if (!card || !btn) return;
btn.addEventListener('click', function() {
var flipped = card.className.indexOf('flipped') !== -1;
if (flipped) {
card.className = 'card';
} else {
card.className = 'card flipped';
}
});
})();
rotateY(180deg) は縦の軸を中心に横方向へ回転(本のページをめくるような動き)。rotateX(180deg) は横の軸を中心に縦方向へ回転(扉が上下に開くような動き)。裏面の初期値も同じ軸で rotateX(180deg) を設定する必要がある点に注意。
④ グループ排他制御(1枚だけ開く)
カードをクリックしてください
Card 1
Back 1
Star
Card 2
Back 2
Sun
Card 3
Back 3
Diamond
<div class="card-group">
<div class="card-wrapper">
<div class="card">
<div class="front"><p>Card 1</p></div>
<div class="back"><p>Back 1</p></div>
</div>
</div>
<div class="card-wrapper">
<div class="card">
<div class="front"><p>Card 2</p></div>
<div class="back"><p>Back 2</p></div>
</div>
</div>
<div class="card-wrapper">
<div class="card">
<div class="front"><p>Card 3</p></div>
<div class="back"><p>Back 3</p></div>
</div>
</div>
</div>
.card-group {
display: flex;
gap: 16px;
justify-content: center;
flex-wrap: wrap;
}
.card-wrapper {
perspective: 600px;
width: 140px;
height: 200px;
cursor: pointer;
}
.card {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
transition: transform 0.6s ease;
}
.card.flipped {
transform: rotateY(180deg);
}
.front,
.back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 12px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
padding: 16px;
box-sizing: border-box;
}
.back {
transform: rotateY(180deg);
background: #f8fafc;
color: #334155;
border: 2px solid #e2e8f0;
}
(function() {
var wrappers = document.querySelectorAll('.card-wrapper');
wrappers.forEach(function(wrapper) {
wrapper.addEventListener('click', function() {
var card = wrapper.querySelector('.card');
if (!card) return;
var nowFlipped = card.className.indexOf('flipped') !== -1;
wrappers.forEach(function(w) {
var c = w.querySelector('.card');
if (c) c.className = 'card';
});
if (!nowFlipped) {
card.className = 'card flipped';
}
});
});
})();
「全閉じ → 対象だけ開く」という 2 ステップで排他制御を実現する。まずすべてのカードから flipped クラスを外し、その後クリックされたカードが開いていなかった場合のみ flipped を付与する。すでに開いていた場合はそのまま閉じた状態になる。
当サイトで公開しているWebデザインやUIの実装例は、一覧として以下記事に纏めています。

