20 / 20
All 20 in 20 CSS Image Hover Effects
- 01CSS Image Hover Zoom In Card
- 02CSS Hover Reveal Text Over Image
- 03E-Commerce Product Image Swap on Hover
- 04CSS Grid Image Blur Overlay Text Hover
- 05CSS Card Slide Up Caption on Hover
- 06CSS Grayscale to Color Image Hover
- 07CSS Image Color Overlay Tint on Hover
- 08Neumorphic Image Card Hover Effect CSS
- 09Glassmorphism Overlay on Image Hover
- 10CSS Glowing Neon Border Image Hover
- 11CSS Image Clip-Path Transition Hover
- 12CSS Image Tilt 3D Perspective Hover
- 13CSS Shining Light Glare Image Hover
- 14CSS Image Split Transition Hover
- 15CSS Image Ripple Animation Hover
- 16Circular Team Profile Avatar Hover CSS
- 17CSS Fullscreen Background Image Hover
- 18CSS Masonry Gallery Zoom Hover
- 19CSS Image Icon Reveal Center Hover
- 20CSS Image Card Flip 3D Animation Hover
CSS Image Card Flip 3D Animation Hover
Cards that rotate 180deg on their Y-axis to reveal a back face with descriptive content, driven entirely by CSS 3D transforms.
Build UI like this from scratch: Flexbox, Grid, animations & responsive CSS
ZTM · The CSS Bootcamp · 30‑day money-back guarantee · Affiliate link
The code
<div class="ih-20">
<div class="ih-20__grid">
<div class="ih-20__scene">
<div class="ih-20__flipper">
<div class="ih-20__front">
<div class="ih-20__front-img ih-20__front-img--1"><span class="ih-20__face-icon">🔭</span></div>
<div class="ih-20__front-label">
<p class="ih-20__front-name">Cosmos Explorer</p>
<p class="ih-20__front-cat">Astrophotography</p>
</div>
<span class="ih-20__hint">Hover to flip</span>
</div>
<div class="ih-20__back ih-20__back--1">
<span class="ih-20__back-icon">🌌</span>
<p class="ih-20__back-title">20-Week Course</p>
<p class="ih-20__back-desc">Master astrophotography from light pollution basics to deep-sky stacking in Photoshop.</p>
<button class="ih-20__back-cta">Enroll Now</button>
</div>
</div>
</div>
<div class="ih-20__scene">
<div class="ih-20__flipper">
<div class="ih-20__front">
<div class="ih-20__front-img ih-20__front-img--2"><span class="ih-20__face-icon">🌿</span></div>
<div class="ih-20__front-label">
<p class="ih-20__front-name">Bio Systems</p>
<p class="ih-20__front-cat">Botany Research</p>
</div>
<span class="ih-20__hint">Hover to flip</span>
</div>
<div class="ih-20__back ih-20__back--2">
<span class="ih-20__back-icon">🧬</span>
<p class="ih-20__back-title">Lab Access</p>
<p class="ih-20__back-desc">12 months of virtual lab sessions with live microscopy and specimen archive access.</p>
<button class="ih-20__back-cta">Join Lab</button>
</div>
</div>
</div>
<div class="ih-20__scene">
<div class="ih-20__flipper">
<div class="ih-20__front">
<div class="ih-20__front-img ih-20__front-img--3"><span class="ih-20__face-icon">🎭</span></div>
<div class="ih-20__front-label">
<p class="ih-20__front-name">Digital Arts</p>
<p class="ih-20__front-cat">Creative Studio</p>
</div>
<span class="ih-20__hint">Hover to flip</span>
</div>
<div class="ih-20__back ih-20__back--3">
<span class="ih-20__back-icon">🎨</span>
<p class="ih-20__back-title">Creator Pack</p>
<p class="ih-20__back-desc">Unlimited generative art tools, 500+ premium assets, and weekly critique sessions.</p>
<button class="ih-20__back-cta">Get Access</button>
</div>
</div>
</div>
</div>
</div><div class="ih-20">
<div class="ih-20__grid">
<div class="ih-20__scene">
<div class="ih-20__flipper">
<div class="ih-20__front">
<div class="ih-20__front-img ih-20__front-img--1"><span class="ih-20__face-icon">🔭</span></div>
<div class="ih-20__front-label">
<p class="ih-20__front-name">Cosmos Explorer</p>
<p class="ih-20__front-cat">Astrophotography</p>
</div>
<span class="ih-20__hint">Hover to flip</span>
</div>
<div class="ih-20__back ih-20__back--1">
<span class="ih-20__back-icon">🌌</span>
<p class="ih-20__back-title">20-Week Course</p>
<p class="ih-20__back-desc">Master astrophotography from light pollution basics to deep-sky stacking in Photoshop.</p>
<button class="ih-20__back-cta">Enroll Now</button>
</div>
</div>
</div>
<div class="ih-20__scene">
<div class="ih-20__flipper">
<div class="ih-20__front">
<div class="ih-20__front-img ih-20__front-img--2"><span class="ih-20__face-icon">🌿</span></div>
<div class="ih-20__front-label">
<p class="ih-20__front-name">Bio Systems</p>
<p class="ih-20__front-cat">Botany Research</p>
</div>
<span class="ih-20__hint">Hover to flip</span>
</div>
<div class="ih-20__back ih-20__back--2">
<span class="ih-20__back-icon">🧬</span>
<p class="ih-20__back-title">Lab Access</p>
<p class="ih-20__back-desc">12 months of virtual lab sessions with live microscopy and specimen archive access.</p>
<button class="ih-20__back-cta">Join Lab</button>
</div>
</div>
</div>
<div class="ih-20__scene">
<div class="ih-20__flipper">
<div class="ih-20__front">
<div class="ih-20__front-img ih-20__front-img--3"><span class="ih-20__face-icon">🎭</span></div>
<div class="ih-20__front-label">
<p class="ih-20__front-name">Digital Arts</p>
<p class="ih-20__front-cat">Creative Studio</p>
</div>
<span class="ih-20__hint">Hover to flip</span>
</div>
<div class="ih-20__back ih-20__back--3">
<span class="ih-20__back-icon">🎨</span>
<p class="ih-20__back-title">Creator Pack</p>
<p class="ih-20__back-desc">Unlimited generative art tools, 500+ premium assets, and weekly critique sessions.</p>
<button class="ih-20__back-cta">Get Access</button>
</div>
</div>
</div>
</div>
</div>.ih-20,
.ih-20 *,
.ih-20 *::before,
.ih-20 *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.ih-20 ::selection {
background: #34d399;
color: #000;
}
.ih-20 {
--accent: #34d399;
--accent2: #818cf8;
--bg: #07070f;
--text: #f1f5f9;
--muted: #64748b;
--duration: 0.65s;
--ease: cubic-bezier(0.45,0,0.55,1);
font-family: system-ui,sans-serif;
background: var(--bg);
padding: 40px 24px;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
perspective: 1000px;
}
.ih-20__grid {
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 20px;
max-width: 780px;
width: 100%;
}
.ih-20__scene {
perspective: 800px;
aspect-ratio: 3/4;
}
/* The flipper: transform-style:preserve-3d is the key */
.ih-20__flipper {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform var(--duration) var(--ease);
cursor: pointer;
}
.ih-20__scene:hover .ih-20__flipper {
transform: rotateY(180deg);
}
/* Both faces share absolute positioning and backface-visibility:hidden */
.ih-20__front,
.ih-20__back {
position: absolute;
inset: 0;
border-radius: 16px;
overflow: hidden;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
/* Back face pre-rotated so it shows on flip */
.ih-20__back {
transform: rotateY(180deg);
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20px;
}
.ih-20__front-img {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
}
.ih-20__front-img--1 {
background: linear-gradient(145deg,#1e1b4b,#312e81,#4338ca,#818cf8);
}
.ih-20__front-img--2 {
background: linear-gradient(145deg,#052e16,#065f46,#059669,#34d399);
}
.ih-20__front-img--3 {
background: linear-gradient(145deg,#3b0764,#6b21a8,#9333ea,#e879f9);
}
.ih-20__back--1 {
background: linear-gradient(135deg,#13103a,#1e1b4b);
}
.ih-20__back--2 {
background: linear-gradient(135deg,#031b10,#052e16);
}
.ih-20__back--3 {
background: linear-gradient(135deg,#230335,#3b0764);
}
.ih-20__face-icon {
font-size: 56px;
opacity: 0.35;
position: relative;
z-index: 1;
}
.ih-20__front-label {
position: relative;
z-index: 1;
padding: 16px;
background: linear-gradient(to top,rgba(0,0,0,0.8),transparent);
}
.ih-20__front-name {
font-size: 14px;
font-weight: 700;
color: var(--text);
}
.ih-20__front-cat {
font-size: 10px;
color: var(--muted);
margin-top: 2px;
}
/* Back content */
.ih-20__back-icon {
font-size: 36px;
margin-bottom: 12px;
}
.ih-20__back-title {
font-size: 15px;
font-weight: 800;
color: var(--text);
text-align: center;
margin-bottom: 8px;
}
.ih-20__back-desc {
font-size: 11px;
color: var(--muted);
text-align: center;
line-height: 1.5;
margin-bottom: 14px;
}
.ih-20__back-cta {
padding: 8px 18px;
border-radius: 24px;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.05em;
color: #000;
background: var(--accent);
border: none;
cursor: pointer;
transition: transform 0.2s ease,box-shadow 0.2s ease;
}
.ih-20__back-cta:hover {
transform: scale(1.04);
box-shadow: 0 0 16px rgba(52,211,153,0.4);
}
.ih-20__back--3 .ih-20__back-cta {
background: #e879f9;
color: #000;
}
.ih-20__back--3 .ih-20__back-cta:hover {
box-shadow: 0 0 16px rgba(232,121,249,0.4);
}
/* Flip hint badge */
.ih-20__hint {
position: absolute;
top: 10px;
right: 10px;
z-index: 2;
background: rgba(255,255,255,0.07);
border: 1px solid rgba(255,255,255,0.1);
border-radius: 20px;
padding: 3px 8px;
font-size: 9px;
font-weight: 700;
color: var(--muted);
transition: opacity 0.3s ease;
}
.ih-20__scene:hover .ih-20__hint {
opacity: 0;
}
@media (prefers-reduced-motion: reduce) {
.ih-20__flipper {
transition: none;
}
.ih-20__scene:hover .ih-20__flipper {
transform: none;
}
}.ih-20,
.ih-20 *,
.ih-20 *::before,
.ih-20 *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.ih-20 ::selection {
background: #34d399;
color: #000;
}
.ih-20 {
--accent: #34d399;
--accent2: #818cf8;
--bg: #07070f;
--text: #f1f5f9;
--muted: #64748b;
--duration: 0.65s;
--ease: cubic-bezier(0.45,0,0.55,1);
font-family: system-ui,sans-serif;
background: var(--bg);
padding: 40px 24px;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
perspective: 1000px;
}
.ih-20__grid {
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 20px;
max-width: 780px;
width: 100%;
}
.ih-20__scene {
perspective: 800px;
aspect-ratio: 3/4;
}
/* The flipper: transform-style:preserve-3d is the key */
.ih-20__flipper {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform var(--duration) var(--ease);
cursor: pointer;
}
.ih-20__scene:hover .ih-20__flipper {
transform: rotateY(180deg);
}
/* Both faces share absolute positioning and backface-visibility:hidden */
.ih-20__front,
.ih-20__back {
position: absolute;
inset: 0;
border-radius: 16px;
overflow: hidden;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
/* Back face pre-rotated so it shows on flip */
.ih-20__back {
transform: rotateY(180deg);
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20px;
}
.ih-20__front-img {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
}
.ih-20__front-img--1 {
background: linear-gradient(145deg,#1e1b4b,#312e81,#4338ca,#818cf8);
}
.ih-20__front-img--2 {
background: linear-gradient(145deg,#052e16,#065f46,#059669,#34d399);
}
.ih-20__front-img--3 {
background: linear-gradient(145deg,#3b0764,#6b21a8,#9333ea,#e879f9);
}
.ih-20__back--1 {
background: linear-gradient(135deg,#13103a,#1e1b4b);
}
.ih-20__back--2 {
background: linear-gradient(135deg,#031b10,#052e16);
}
.ih-20__back--3 {
background: linear-gradient(135deg,#230335,#3b0764);
}
.ih-20__face-icon {
font-size: 56px;
opacity: 0.35;
position: relative;
z-index: 1;
}
.ih-20__front-label {
position: relative;
z-index: 1;
padding: 16px;
background: linear-gradient(to top,rgba(0,0,0,0.8),transparent);
}
.ih-20__front-name {
font-size: 14px;
font-weight: 700;
color: var(--text);
}
.ih-20__front-cat {
font-size: 10px;
color: var(--muted);
margin-top: 2px;
}
/* Back content */
.ih-20__back-icon {
font-size: 36px;
margin-bottom: 12px;
}
.ih-20__back-title {
font-size: 15px;
font-weight: 800;
color: var(--text);
text-align: center;
margin-bottom: 8px;
}
.ih-20__back-desc {
font-size: 11px;
color: var(--muted);
text-align: center;
line-height: 1.5;
margin-bottom: 14px;
}
.ih-20__back-cta {
padding: 8px 18px;
border-radius: 24px;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.05em;
color: #000;
background: var(--accent);
border: none;
cursor: pointer;
transition: transform 0.2s ease,box-shadow 0.2s ease;
}
.ih-20__back-cta:hover {
transform: scale(1.04);
box-shadow: 0 0 16px rgba(52,211,153,0.4);
}
.ih-20__back--3 .ih-20__back-cta {
background: #e879f9;
color: #000;
}
.ih-20__back--3 .ih-20__back-cta:hover {
box-shadow: 0 0 16px rgba(232,121,249,0.4);
}
/* Flip hint badge */
.ih-20__hint {
position: absolute;
top: 10px;
right: 10px;
z-index: 2;
background: rgba(255,255,255,0.07);
border: 1px solid rgba(255,255,255,0.1);
border-radius: 20px;
padding: 3px 8px;
font-size: 9px;
font-weight: 700;
color: var(--muted);
transition: opacity 0.3s ease;
}
.ih-20__scene:hover .ih-20__hint {
opacity: 0;
}
@media (prefers-reduced-motion: reduce) {
.ih-20__flipper {
transition: none;
}
.ih-20__scene:hover .ih-20__flipper {
transform: none;
}
}Here's a working CSS Image Hover Effect from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Image Card Flip 3D Animation Hover
Source: https://codefronts.com/motion/css-image-hover-effects/css-image-card-flip-3d-animation-hover/
Cards that rotate 180deg on their Y-axis to reveal a back face with descriptive content, driven entirely by CSS 3D transforms.
## HTML
```html
<div class="ih-20">
<div class="ih-20__grid">
<div class="ih-20__scene">
<div class="ih-20__flipper">
<div class="ih-20__front">
<div class="ih-20__front-img ih-20__front-img--1"><span class="ih-20__face-icon">🔭</span></div>
<div class="ih-20__front-label">
<p class="ih-20__front-name">Cosmos Explorer</p>
<p class="ih-20__front-cat">Astrophotography</p>
</div>
<span class="ih-20__hint">Hover to flip</span>
</div>
<div class="ih-20__back ih-20__back--1">
<span class="ih-20__back-icon">🌌</span>
<p class="ih-20__back-title">20-Week Course</p>
<p class="ih-20__back-desc">Master astrophotography from light pollution basics to deep-sky stacking in Photoshop.</p>
<button class="ih-20__back-cta">Enroll Now</button>
</div>
</div>
</div>
<div class="ih-20__scene">
<div class="ih-20__flipper">
<div class="ih-20__front">
<div class="ih-20__front-img ih-20__front-img--2"><span class="ih-20__face-icon">🌿</span></div>
<div class="ih-20__front-label">
<p class="ih-20__front-name">Bio Systems</p>
<p class="ih-20__front-cat">Botany Research</p>
</div>
<span class="ih-20__hint">Hover to flip</span>
</div>
<div class="ih-20__back ih-20__back--2">
<span class="ih-20__back-icon">🧬</span>
<p class="ih-20__back-title">Lab Access</p>
<p class="ih-20__back-desc">12 months of virtual lab sessions with live microscopy and specimen archive access.</p>
<button class="ih-20__back-cta">Join Lab</button>
</div>
</div>
</div>
<div class="ih-20__scene">
<div class="ih-20__flipper">
<div class="ih-20__front">
<div class="ih-20__front-img ih-20__front-img--3"><span class="ih-20__face-icon">🎭</span></div>
<div class="ih-20__front-label">
<p class="ih-20__front-name">Digital Arts</p>
<p class="ih-20__front-cat">Creative Studio</p>
</div>
<span class="ih-20__hint">Hover to flip</span>
</div>
<div class="ih-20__back ih-20__back--3">
<span class="ih-20__back-icon">🎨</span>
<p class="ih-20__back-title">Creator Pack</p>
<p class="ih-20__back-desc">Unlimited generative art tools, 500+ premium assets, and weekly critique sessions.</p>
<button class="ih-20__back-cta">Get Access</button>
</div>
</div>
</div>
</div>
</div>
```
## CSS
```css
.ih-20,
.ih-20 *,
.ih-20 *::before,
.ih-20 *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.ih-20 ::selection {
background: #34d399;
color: #000;
}
.ih-20 {
--accent: #34d399;
--accent2: #818cf8;
--bg: #07070f;
--text: #f1f5f9;
--muted: #64748b;
--duration: 0.65s;
--ease: cubic-bezier(0.45,0,0.55,1);
font-family: system-ui,sans-serif;
background: var(--bg);
padding: 40px 24px;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
perspective: 1000px;
}
.ih-20__grid {
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 20px;
max-width: 780px;
width: 100%;
}
.ih-20__scene {
perspective: 800px;
aspect-ratio: 3/4;
}
/* The flipper: transform-style:preserve-3d is the key */
.ih-20__flipper {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform var(--duration) var(--ease);
cursor: pointer;
}
.ih-20__scene:hover .ih-20__flipper {
transform: rotateY(180deg);
}
/* Both faces share absolute positioning and backface-visibility:hidden */
.ih-20__front,
.ih-20__back {
position: absolute;
inset: 0;
border-radius: 16px;
overflow: hidden;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
/* Back face pre-rotated so it shows on flip */
.ih-20__back {
transform: rotateY(180deg);
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20px;
}
.ih-20__front-img {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
}
.ih-20__front-img--1 {
background: linear-gradient(145deg,#1e1b4b,#312e81,#4338ca,#818cf8);
}
.ih-20__front-img--2 {
background: linear-gradient(145deg,#052e16,#065f46,#059669,#34d399);
}
.ih-20__front-img--3 {
background: linear-gradient(145deg,#3b0764,#6b21a8,#9333ea,#e879f9);
}
.ih-20__back--1 {
background: linear-gradient(135deg,#13103a,#1e1b4b);
}
.ih-20__back--2 {
background: linear-gradient(135deg,#031b10,#052e16);
}
.ih-20__back--3 {
background: linear-gradient(135deg,#230335,#3b0764);
}
.ih-20__face-icon {
font-size: 56px;
opacity: 0.35;
position: relative;
z-index: 1;
}
.ih-20__front-label {
position: relative;
z-index: 1;
padding: 16px;
background: linear-gradient(to top,rgba(0,0,0,0.8),transparent);
}
.ih-20__front-name {
font-size: 14px;
font-weight: 700;
color: var(--text);
}
.ih-20__front-cat {
font-size: 10px;
color: var(--muted);
margin-top: 2px;
}
/* Back content */
.ih-20__back-icon {
font-size: 36px;
margin-bottom: 12px;
}
.ih-20__back-title {
font-size: 15px;
font-weight: 800;
color: var(--text);
text-align: center;
margin-bottom: 8px;
}
.ih-20__back-desc {
font-size: 11px;
color: var(--muted);
text-align: center;
line-height: 1.5;
margin-bottom: 14px;
}
.ih-20__back-cta {
padding: 8px 18px;
border-radius: 24px;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.05em;
color: #000;
background: var(--accent);
border: none;
cursor: pointer;
transition: transform 0.2s ease,box-shadow 0.2s ease;
}
.ih-20__back-cta:hover {
transform: scale(1.04);
box-shadow: 0 0 16px rgba(52,211,153,0.4);
}
.ih-20__back--3 .ih-20__back-cta {
background: #e879f9;
color: #000;
}
.ih-20__back--3 .ih-20__back-cta:hover {
box-shadow: 0 0 16px rgba(232,121,249,0.4);
}
/* Flip hint badge */
.ih-20__hint {
position: absolute;
top: 10px;
right: 10px;
z-index: 2;
background: rgba(255,255,255,0.07);
border: 1px solid rgba(255,255,255,0.1);
border-radius: 20px;
padding: 3px 8px;
font-size: 9px;
font-weight: 700;
color: var(--muted);
transition: opacity 0.3s ease;
}
.ih-20__scene:hover .ih-20__hint {
opacity: 0;
}
@media (prefers-reduced-motion: reduce) {
.ih-20__flipper {
transition: none;
}
.ih-20__scene:hover .ih-20__flipper {
transform: none;
}
}
```Here's a working CSS Image Hover Effect from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Image Card Flip 3D Animation Hover
Source: https://codefronts.com/motion/css-image-hover-effects/css-image-card-flip-3d-animation-hover/
Cards that rotate 180deg on their Y-axis to reveal a back face with descriptive content, driven entirely by CSS 3D transforms.
## HTML
```html
<div class="ih-20">
<div class="ih-20__grid">
<div class="ih-20__scene">
<div class="ih-20__flipper">
<div class="ih-20__front">
<div class="ih-20__front-img ih-20__front-img--1"><span class="ih-20__face-icon">🔭</span></div>
<div class="ih-20__front-label">
<p class="ih-20__front-name">Cosmos Explorer</p>
<p class="ih-20__front-cat">Astrophotography</p>
</div>
<span class="ih-20__hint">Hover to flip</span>
</div>
<div class="ih-20__back ih-20__back--1">
<span class="ih-20__back-icon">🌌</span>
<p class="ih-20__back-title">20-Week Course</p>
<p class="ih-20__back-desc">Master astrophotography from light pollution basics to deep-sky stacking in Photoshop.</p>
<button class="ih-20__back-cta">Enroll Now</button>
</div>
</div>
</div>
<div class="ih-20__scene">
<div class="ih-20__flipper">
<div class="ih-20__front">
<div class="ih-20__front-img ih-20__front-img--2"><span class="ih-20__face-icon">🌿</span></div>
<div class="ih-20__front-label">
<p class="ih-20__front-name">Bio Systems</p>
<p class="ih-20__front-cat">Botany Research</p>
</div>
<span class="ih-20__hint">Hover to flip</span>
</div>
<div class="ih-20__back ih-20__back--2">
<span class="ih-20__back-icon">🧬</span>
<p class="ih-20__back-title">Lab Access</p>
<p class="ih-20__back-desc">12 months of virtual lab sessions with live microscopy and specimen archive access.</p>
<button class="ih-20__back-cta">Join Lab</button>
</div>
</div>
</div>
<div class="ih-20__scene">
<div class="ih-20__flipper">
<div class="ih-20__front">
<div class="ih-20__front-img ih-20__front-img--3"><span class="ih-20__face-icon">🎭</span></div>
<div class="ih-20__front-label">
<p class="ih-20__front-name">Digital Arts</p>
<p class="ih-20__front-cat">Creative Studio</p>
</div>
<span class="ih-20__hint">Hover to flip</span>
</div>
<div class="ih-20__back ih-20__back--3">
<span class="ih-20__back-icon">🎨</span>
<p class="ih-20__back-title">Creator Pack</p>
<p class="ih-20__back-desc">Unlimited generative art tools, 500+ premium assets, and weekly critique sessions.</p>
<button class="ih-20__back-cta">Get Access</button>
</div>
</div>
</div>
</div>
</div>
```
## CSS
```css
.ih-20,
.ih-20 *,
.ih-20 *::before,
.ih-20 *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.ih-20 ::selection {
background: #34d399;
color: #000;
}
.ih-20 {
--accent: #34d399;
--accent2: #818cf8;
--bg: #07070f;
--text: #f1f5f9;
--muted: #64748b;
--duration: 0.65s;
--ease: cubic-bezier(0.45,0,0.55,1);
font-family: system-ui,sans-serif;
background: var(--bg);
padding: 40px 24px;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
perspective: 1000px;
}
.ih-20__grid {
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 20px;
max-width: 780px;
width: 100%;
}
.ih-20__scene {
perspective: 800px;
aspect-ratio: 3/4;
}
/* The flipper: transform-style:preserve-3d is the key */
.ih-20__flipper {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform var(--duration) var(--ease);
cursor: pointer;
}
.ih-20__scene:hover .ih-20__flipper {
transform: rotateY(180deg);
}
/* Both faces share absolute positioning and backface-visibility:hidden */
.ih-20__front,
.ih-20__back {
position: absolute;
inset: 0;
border-radius: 16px;
overflow: hidden;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
/* Back face pre-rotated so it shows on flip */
.ih-20__back {
transform: rotateY(180deg);
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20px;
}
.ih-20__front-img {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
}
.ih-20__front-img--1 {
background: linear-gradient(145deg,#1e1b4b,#312e81,#4338ca,#818cf8);
}
.ih-20__front-img--2 {
background: linear-gradient(145deg,#052e16,#065f46,#059669,#34d399);
}
.ih-20__front-img--3 {
background: linear-gradient(145deg,#3b0764,#6b21a8,#9333ea,#e879f9);
}
.ih-20__back--1 {
background: linear-gradient(135deg,#13103a,#1e1b4b);
}
.ih-20__back--2 {
background: linear-gradient(135deg,#031b10,#052e16);
}
.ih-20__back--3 {
background: linear-gradient(135deg,#230335,#3b0764);
}
.ih-20__face-icon {
font-size: 56px;
opacity: 0.35;
position: relative;
z-index: 1;
}
.ih-20__front-label {
position: relative;
z-index: 1;
padding: 16px;
background: linear-gradient(to top,rgba(0,0,0,0.8),transparent);
}
.ih-20__front-name {
font-size: 14px;
font-weight: 700;
color: var(--text);
}
.ih-20__front-cat {
font-size: 10px;
color: var(--muted);
margin-top: 2px;
}
/* Back content */
.ih-20__back-icon {
font-size: 36px;
margin-bottom: 12px;
}
.ih-20__back-title {
font-size: 15px;
font-weight: 800;
color: var(--text);
text-align: center;
margin-bottom: 8px;
}
.ih-20__back-desc {
font-size: 11px;
color: var(--muted);
text-align: center;
line-height: 1.5;
margin-bottom: 14px;
}
.ih-20__back-cta {
padding: 8px 18px;
border-radius: 24px;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.05em;
color: #000;
background: var(--accent);
border: none;
cursor: pointer;
transition: transform 0.2s ease,box-shadow 0.2s ease;
}
.ih-20__back-cta:hover {
transform: scale(1.04);
box-shadow: 0 0 16px rgba(52,211,153,0.4);
}
.ih-20__back--3 .ih-20__back-cta {
background: #e879f9;
color: #000;
}
.ih-20__back--3 .ih-20__back-cta:hover {
box-shadow: 0 0 16px rgba(232,121,249,0.4);
}
/* Flip hint badge */
.ih-20__hint {
position: absolute;
top: 10px;
right: 10px;
z-index: 2;
background: rgba(255,255,255,0.07);
border: 1px solid rgba(255,255,255,0.1);
border-radius: 20px;
padding: 3px 8px;
font-size: 9px;
font-weight: 700;
color: var(--muted);
transition: opacity 0.3s ease;
}
.ih-20__scene:hover .ih-20__hint {
opacity: 0;
}
@media (prefers-reduced-motion: reduce) {
.ih-20__flipper {
transition: none;
}
.ih-20__scene:hover .ih-20__flipper {
transform: none;
}
}
```How this works
The card uses a three-layer structure: a .scene with perspective: 800px, a .flipper with transform-style: preserve-3d, and two face divs. The back face is pre-rotated with transform: rotateY(180deg). Both faces have backface-visibility: hidden, which hides each face when it is rotated beyond 90deg from the viewer. On hover, the flipper element transitions to rotateY(180deg), bringing the back face into view and hiding the front.
The transform-style: preserve-3d on the flipper is the critical property — without it, both faces flatten into 2D and the flip degenerates into a scale-to-zero then scale-from-zero effect. The perspective on the scene parent provides the 3D depth context without affecting the layout of surrounding elements.
Make it yours
- Switch from Y-axis to X-axis flip by changing
rotateY(180deg)torotateX(180deg)on both the back face and the hover state. - Adjust flip speed with
--duration: 0.4sfor a snappy pop or0.9sfor a slow cinematic turn. - Add a slight
scale(1.03)at the midpoint using keyframes on the flipper to make the card appear to grow during the flip. - For an "open book" effect, use two
rotateY(90deg)stages (first half and second half) coordinated with an animation rather than a transition. - Place a video element on the back face that starts playing when the flip is triggered via a short JavaScript
transitionendlistener.
Gotchas — read before shipping
backface-visibility: hiddenrequires the-webkit-prefix in Safari — always include-webkit-backface-visibility: hiddenalongside the standard property.overflow: hiddenon the flipper element breakstransform-style: preserve-3din all browsers — never combine these two properties on the same element.- On Firefox, elements inside a 3D-transformed container may render with subpixel artefacts on the face edges — a 1px transparent border (
border: 1px solid transparent) on the face elements often resolves this.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 36+ | 9+ (-webkit- prefixes required) | 16+ | 36+ |
Always include -webkit-backface-visibility and -webkit-transform-style for Safari; test flip direction on iOS where perspective can behave differently.