30 CSS Hover Effects 13 / 30
CSS 3D Tilt Card Hover Effect
Four card hover effects with perspective-based 3D depth — static tilt corner, perspective flip-axis, floating lift with shadow depth, and layered parallax layers — using CSS perspective, rotateX/Y transforms, and transform-style: preserve-3d.
This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.
The code
<div class="hv-13">
<div class="hv-13__grid">
<div class="hv-13__scene">
<div class="hv-13__card hv-13__card--tilt">
<div class="hv-13__card-body">
<div class="hv-13__icon">◈</div>
<h3 class="hv-13__title">Static Tilt</h3>
<p class="hv-13__text">Perspective rotateX + rotateY on hover</p>
</div>
</div>
</div>
<div class="hv-13__scene">
<div class="hv-13__card hv-13__card--flip">
<div class="hv-13__card-body">
<div class="hv-13__icon">⬡</div>
<h3 class="hv-13__title">Axis Flip</h3>
<p class="hv-13__text">rotateY 180° perspective reveal</p>
</div>
</div>
</div>
<div class="hv-13__scene hv-13__scene--lift">
<div class="hv-13__card hv-13__card--lift">
<div class="hv-13__card-body">
<div class="hv-13__icon">▲</div>
<h3 class="hv-13__title">Float Lift</h3>
<p class="hv-13__text">translateY + shadow depth</p>
</div>
</div>
</div>
<div class="hv-13__scene">
<div class="hv-13__card hv-13__card--layers">
<div class="hv-13__layer hv-13__layer--bg"></div>
<div class="hv-13__layer hv-13__layer--mid">
<div class="hv-13__icon">◉</div>
</div>
<div class="hv-13__layer hv-13__layer--top">
<h3 class="hv-13__title">Parallax</h3>
<p class="hv-13__text">translateZ layered depth</p>
</div>
</div>
</div>
</div>
</div> <div class="hv-13">
<div class="hv-13__grid">
<div class="hv-13__scene">
<div class="hv-13__card hv-13__card--tilt">
<div class="hv-13__card-body">
<div class="hv-13__icon">◈</div>
<h3 class="hv-13__title">Static Tilt</h3>
<p class="hv-13__text">Perspective rotateX + rotateY on hover</p>
</div>
</div>
</div>
<div class="hv-13__scene">
<div class="hv-13__card hv-13__card--flip">
<div class="hv-13__card-body">
<div class="hv-13__icon">⬡</div>
<h3 class="hv-13__title">Axis Flip</h3>
<p class="hv-13__text">rotateY 180° perspective reveal</p>
</div>
</div>
</div>
<div class="hv-13__scene hv-13__scene--lift">
<div class="hv-13__card hv-13__card--lift">
<div class="hv-13__card-body">
<div class="hv-13__icon">▲</div>
<h3 class="hv-13__title">Float Lift</h3>
<p class="hv-13__text">translateY + shadow depth</p>
</div>
</div>
</div>
<div class="hv-13__scene">
<div class="hv-13__card hv-13__card--layers">
<div class="hv-13__layer hv-13__layer--bg"></div>
<div class="hv-13__layer hv-13__layer--mid">
<div class="hv-13__icon">◉</div>
</div>
<div class="hv-13__layer hv-13__layer--top">
<h3 class="hv-13__title">Parallax</h3>
<p class="hv-13__text">translateZ layered depth</p>
</div>
</div>
</div>
</div>
</div>.hv-13,.hv-13 *,.hv-13 *::before,.hv-13 *::after{box-sizing:border-box;margin:0;padding:0}
.hv-13 ::selection{background:#0284c7;color:#fff}
.hv-13{
--bg:#020810;
--text:#bae6fd;
--dim:#475569;
--blue:#0ea5e9;
--sky:#38bdf8;
--indigo:#6366f1;
--teal:#14b8a6;
font-family:'Segoe UI',system-ui,sans-serif;
background:var(--bg);
min-height:100vh;
display:flex;align-items:center;justify-content:center;
padding:60px 24px;
}
.hv-13__grid{
display:grid;grid-template-columns:repeat(2,1fr);gap:40px;
max-width:760px;width:100%;
}
.hv-13__scene{
perspective:800px;
}
.hv-13__card{
width:100%;min-height:220px;
border-radius:16px;
background:rgba(255,255,255,.04);
border:1px solid rgba(255,255,255,.1);
transition:transform .4s cubic-bezier(.4,0,.2,1),box-shadow .4s;
transform-style:preserve-3d;
cursor:pointer;
}
.hv-13__card-body{
padding:32px;display:flex;flex-direction:column;gap:12px;
}
.hv-13__icon{font-size:2rem;color:var(--blue)}
.hv-13__title{font-size:1.1rem;font-weight:700;color:var(--text)}
.hv-13__text{font-size:.85rem;color:var(--dim);line-height:1.5}
/* 1 — static tilt */
.hv-13__card--tilt:hover{
transform:rotateX(8deg) rotateY(-8deg);
box-shadow:8px 12px 40px rgba(14,165,233,.3);
}
/* 2 — axis flip */
.hv-13__card--flip{
border-color:rgba(99,102,241,.3);
}
.hv-13__card--flip .hv-13__icon{color:var(--indigo)}
.hv-13__card--flip:hover{
transform:rotateX(-6deg) rotateY(10deg);
box-shadow:-10px 8px 40px rgba(99,102,241,.3);
border-color:rgba(99,102,241,.6);
}
/* 3 — float lift */
.hv-13__card--lift{
border-color:rgba(20,184,166,.3);
box-shadow:0 4px 20px rgba(0,0,0,.4);
transition:transform .4s cubic-bezier(.4,0,.2,1),box-shadow .4s;
}
.hv-13__card--lift .hv-13__icon{color:var(--teal)}
.hv-13__card--lift:hover{
transform:translateY(-14px);
box-shadow:0 28px 60px rgba(0,0,0,.5),0 0 30px rgba(20,184,166,.2);
}
/* 4 — parallax layers */
.hv-13__card--layers{
position:relative;min-height:220px;overflow:visible;
transition:transform .4s cubic-bezier(.4,0,.2,1);
border-color:rgba(56,189,248,.3);
}
.hv-13__card--layers:hover{
transform:rotateX(6deg) rotateY(-6deg);
}
.hv-13__layer{
position:absolute;inset:0;border-radius:16px;
transition:transform .4s cubic-bezier(.4,0,.2,1);
}
.hv-13__layer--bg{
background:linear-gradient(135deg,rgba(14,165,233,.1),rgba(56,189,248,.05));
}
.hv-13__layer--mid{
display:flex;align-items:flex-start;padding:32px;
}
.hv-13__layer--mid .hv-13__icon{color:var(--sky);font-size:2.5rem}
.hv-13__card--layers:hover .hv-13__layer--mid{transform:translateZ(20px) translateY(-6px)}
.hv-13__layer--top{
display:flex;flex-direction:column;justify-content:flex-end;
padding:28px;gap:8px;
}
.hv-13__card--layers:hover .hv-13__layer--top{transform:translateZ(35px) translateY(-4px)}
@media(max-width:520px){.hv-13__grid{grid-template-columns:1fr}}
@media(prefers-reduced-motion:reduce){
.hv-13__card,.hv-13__layer{transition:none!important}
} .hv-13,.hv-13 *,.hv-13 *::before,.hv-13 *::after{box-sizing:border-box;margin:0;padding:0}
.hv-13 ::selection{background:#0284c7;color:#fff}
.hv-13{
--bg:#020810;
--text:#bae6fd;
--dim:#475569;
--blue:#0ea5e9;
--sky:#38bdf8;
--indigo:#6366f1;
--teal:#14b8a6;
font-family:'Segoe UI',system-ui,sans-serif;
background:var(--bg);
min-height:100vh;
display:flex;align-items:center;justify-content:center;
padding:60px 24px;
}
.hv-13__grid{
display:grid;grid-template-columns:repeat(2,1fr);gap:40px;
max-width:760px;width:100%;
}
.hv-13__scene{
perspective:800px;
}
.hv-13__card{
width:100%;min-height:220px;
border-radius:16px;
background:rgba(255,255,255,.04);
border:1px solid rgba(255,255,255,.1);
transition:transform .4s cubic-bezier(.4,0,.2,1),box-shadow .4s;
transform-style:preserve-3d;
cursor:pointer;
}
.hv-13__card-body{
padding:32px;display:flex;flex-direction:column;gap:12px;
}
.hv-13__icon{font-size:2rem;color:var(--blue)}
.hv-13__title{font-size:1.1rem;font-weight:700;color:var(--text)}
.hv-13__text{font-size:.85rem;color:var(--dim);line-height:1.5}
/* 1 — static tilt */
.hv-13__card--tilt:hover{
transform:rotateX(8deg) rotateY(-8deg);
box-shadow:8px 12px 40px rgba(14,165,233,.3);
}
/* 2 — axis flip */
.hv-13__card--flip{
border-color:rgba(99,102,241,.3);
}
.hv-13__card--flip .hv-13__icon{color:var(--indigo)}
.hv-13__card--flip:hover{
transform:rotateX(-6deg) rotateY(10deg);
box-shadow:-10px 8px 40px rgba(99,102,241,.3);
border-color:rgba(99,102,241,.6);
}
/* 3 — float lift */
.hv-13__card--lift{
border-color:rgba(20,184,166,.3);
box-shadow:0 4px 20px rgba(0,0,0,.4);
transition:transform .4s cubic-bezier(.4,0,.2,1),box-shadow .4s;
}
.hv-13__card--lift .hv-13__icon{color:var(--teal)}
.hv-13__card--lift:hover{
transform:translateY(-14px);
box-shadow:0 28px 60px rgba(0,0,0,.5),0 0 30px rgba(20,184,166,.2);
}
/* 4 — parallax layers */
.hv-13__card--layers{
position:relative;min-height:220px;overflow:visible;
transition:transform .4s cubic-bezier(.4,0,.2,1);
border-color:rgba(56,189,248,.3);
}
.hv-13__card--layers:hover{
transform:rotateX(6deg) rotateY(-6deg);
}
.hv-13__layer{
position:absolute;inset:0;border-radius:16px;
transition:transform .4s cubic-bezier(.4,0,.2,1);
}
.hv-13__layer--bg{
background:linear-gradient(135deg,rgba(14,165,233,.1),rgba(56,189,248,.05));
}
.hv-13__layer--mid{
display:flex;align-items:flex-start;padding:32px;
}
.hv-13__layer--mid .hv-13__icon{color:var(--sky);font-size:2.5rem}
.hv-13__card--layers:hover .hv-13__layer--mid{transform:translateZ(20px) translateY(-6px)}
.hv-13__layer--top{
display:flex;flex-direction:column;justify-content:flex-end;
padding:28px;gap:8px;
}
.hv-13__card--layers:hover .hv-13__layer--top{transform:translateZ(35px) translateY(-4px)}
@media(max-width:520px){.hv-13__grid{grid-template-columns:1fr}}
@media(prefers-reduced-motion:reduce){
.hv-13__card,.hv-13__layer{transition:none!important}
}How this works
CSS 3D tilt requires three elements working together: the wrapper sets perspective: 800px to establish a vanishing point, the card uses transform-style: preserve-3d so child layers exist in the same 3D space, and the hover state applies rotateX(8deg) rotateY(-8deg) to tilt the face. The fixed angle approach (no JS cursor tracking) achieves a convincing 3D still by choosing a consistent diagonal tilt that creates depth without requiring mouse position data.
The floating lift variant doesn't rotate at all — instead it uses translateY(-12px) combined with a larger spread box-shadow (0 24px 60px rgba(0,0,0,.5)) whose offset grows as the card rises, simulating a real object casting a longer shadow as it moves away from the surface. The parallax layer card uses translateZ() on child elements to offset them at different depths, creating a layered parallax that the perspective makes visible even without cursor tracking.
Customize
- Steepen the tilt by increasing from
rotateX(8deg)torotateX(14deg)— values above 20deg look exaggerated and break readable text. - Change the perspective distance with
perspective: 600pxfor a more extreme fish-eye effect orperspective: 1200pxfor a subtle, almost-flat tilt. - Add a specular highlight with a
::beforegradient overlay that also rotates on hover, simulating light reflecting off the tilted card face. - Combine with a
filter: drop-shadow()instead ofbox-shadow— drop-shadow follows the card's transformed outline for a more accurate 3D cast shadow. - Add a
transition-duration: .1son hover and.4son mouse-out for an asymmetric fast-tilt / slow-return feel.
Watch out for
transform-style: preserve-3dis ignored on elements withoverflow: hidden— do not combine these properties or child 3D transforms will be flattened.- The card border and background must be on the same element — applying a
border-radiusparent withperspectiveand a child withtransformcan cause Safari to render the radius incorrectly in 3D. will-change: transformon the tilt card pre-promotes it to a GPU layer — useful for performance but can cause z-index stacking context issues with overlapping siblings.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 60+ | 12+ | 60+ | 60+ |
transform-style: preserve-3d is fully supported. Safari has minor quirks with overflow+3d combinations.