20 CSS Image Hover Effects 20 / 20
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.
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}}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.
Customize
- 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.
Watch out for
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.