22 CSS Transition Effects 16 / 22
Card Tilt 3D Hover
Four cards with CSS custom property glare driven by --gx/--gy, floating gradient orbs with parallax offset, JS mousemove rotating up to 18 degrees.
This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.
The code
<h1>3D Card Tilt Effect</h1>
<p class="sub">Move your cursor over each card — perspective tilt with specular glare highlight</p>
<div class="grid">
<div class="tilt-wrap tc1" id="c1">
<div class="tilt-card">
<div class="tilt-glare"></div>
<div class="tilt-inner">
<div class="tc-float" style="width:120px;height:120px;background:radial-gradient(#a78bfa,transparent);top:-30px;right:-30px;opacity:.4"></div>
<div><div class="tc-badge">✦ Premium</div></div>
<div>
<span class="tc-icon">💎</span>
<div class="tc-title">Holographic Card</div>
<div class="tc-desc">CSS 3D tilt with a rotating conic gradient shimmer and a radial specular glare that follows your cursor.</div>
</div>
<div class="tc-footer">
<span class="tc-action">Explore → </span>
<span class="tc-stat">perspective: 1000px</span>
</div>
</div>
</div>
</div>
<div class="tilt-wrap tc2" id="c2">
<div class="tilt-card">
<div class="tilt-glare"></div>
<div class="tilt-inner">
<div class="tc-float" style="width:100px;height:100px;background:radial-gradient(#fbbf24,transparent);bottom:-20px;left:-20px;opacity:.3"></div>
<div><div class="tc-badge">★ Gold tier</div></div>
<div>
<span class="tc-icon">🏆</span>
<div class="tc-title">Gold Edition</div>
<div class="tc-desc">Warm amber gradient with a soft radial bloom. The tilt depth is controlled by JavaScript reading mousemove coordinates.</div>
</div>
<div class="tc-footer">
<span class="tc-action">Unlock →</span>
<span class="tc-stat">rotateX + rotateY</span>
</div>
</div>
</div>
</div>
<div class="tilt-wrap tc3" id="c3">
<div class="tilt-card">
<div class="tilt-glare"></div>
<div class="tilt-inner">
<div class="tc-float" style="width:80px;height:80px;background:radial-gradient(#34d399,transparent);top:50%;right:10%;opacity:.25"></div>
<div><div class="tc-badge">◈ Active</div></div>
<div>
<span class="tc-icon">⚡</span>
<div class="tc-title">Neon Green</div>
<div class="tc-desc">Deep forest background with teal glow accents. Floating gradient orbs shift with a parallax offset during tilt.</div>
</div>
<div class="tc-footer">
<span class="tc-action">Connect →</span>
<span class="tc-stat">will-change: transform</span>
</div>
</div>
</div>
</div>
<div class="tilt-wrap tc4" id="c4">
<div class="tilt-card">
<div class="tilt-glare"></div>
<div class="tilt-inner">
<div class="tc-float" style="width:160px;height:160px;background:radial-gradient(rgba(148,163,184,.15),transparent);top:-40px;left:-40px"></div>
<div><div class="tc-badge">◻ Standard</div></div>
<div>
<span class="tc-icon">🔮</span>
<div class="tc-title">Chrome Grid</div>
<div class="tc-desc">Diagonal grid texture with silver accents. The glare layer uses a CSS custom property for real-time cursor tracking.</div>
</div>
<div class="tc-footer">
<span class="tc-action">Preview →</span>
<span class="tc-stat">--gx/--gy props</span>
</div>
</div>
</div>
</div>
</div> <h1>3D Card Tilt Effect</h1>
<p class="sub">Move your cursor over each card — perspective tilt with specular glare highlight</p>
<div class="grid">
<div class="tilt-wrap tc1" id="c1">
<div class="tilt-card">
<div class="tilt-glare"></div>
<div class="tilt-inner">
<div class="tc-float" style="width:120px;height:120px;background:radial-gradient(#a78bfa,transparent);top:-30px;right:-30px;opacity:.4"></div>
<div><div class="tc-badge">✦ Premium</div></div>
<div>
<span class="tc-icon">💎</span>
<div class="tc-title">Holographic Card</div>
<div class="tc-desc">CSS 3D tilt with a rotating conic gradient shimmer and a radial specular glare that follows your cursor.</div>
</div>
<div class="tc-footer">
<span class="tc-action">Explore → </span>
<span class="tc-stat">perspective: 1000px</span>
</div>
</div>
</div>
</div>
<div class="tilt-wrap tc2" id="c2">
<div class="tilt-card">
<div class="tilt-glare"></div>
<div class="tilt-inner">
<div class="tc-float" style="width:100px;height:100px;background:radial-gradient(#fbbf24,transparent);bottom:-20px;left:-20px;opacity:.3"></div>
<div><div class="tc-badge">★ Gold tier</div></div>
<div>
<span class="tc-icon">🏆</span>
<div class="tc-title">Gold Edition</div>
<div class="tc-desc">Warm amber gradient with a soft radial bloom. The tilt depth is controlled by JavaScript reading mousemove coordinates.</div>
</div>
<div class="tc-footer">
<span class="tc-action">Unlock →</span>
<span class="tc-stat">rotateX + rotateY</span>
</div>
</div>
</div>
</div>
<div class="tilt-wrap tc3" id="c3">
<div class="tilt-card">
<div class="tilt-glare"></div>
<div class="tilt-inner">
<div class="tc-float" style="width:80px;height:80px;background:radial-gradient(#34d399,transparent);top:50%;right:10%;opacity:.25"></div>
<div><div class="tc-badge">◈ Active</div></div>
<div>
<span class="tc-icon">⚡</span>
<div class="tc-title">Neon Green</div>
<div class="tc-desc">Deep forest background with teal glow accents. Floating gradient orbs shift with a parallax offset during tilt.</div>
</div>
<div class="tc-footer">
<span class="tc-action">Connect →</span>
<span class="tc-stat">will-change: transform</span>
</div>
</div>
</div>
</div>
<div class="tilt-wrap tc4" id="c4">
<div class="tilt-card">
<div class="tilt-glare"></div>
<div class="tilt-inner">
<div class="tc-float" style="width:160px;height:160px;background:radial-gradient(rgba(148,163,184,.15),transparent);top:-40px;left:-40px"></div>
<div><div class="tc-badge">◻ Standard</div></div>
<div>
<span class="tc-icon">🔮</span>
<div class="tc-title">Chrome Grid</div>
<div class="tc-desc">Diagonal grid texture with silver accents. The glare layer uses a CSS custom property for real-time cursor tracking.</div>
</div>
<div class="tc-footer">
<span class="tc-action">Preview →</span>
<span class="tc-stat">--gx/--gy props</span>
</div>
</div>
</div>
</div>
</div>@import url('https://fonts.googleapis.com/css2?family=Clash+Display:wght@400;600;700&family=General+Sans:wght@300;400;500;600&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap');
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Outfit',sans-serif;background:radial-gradient(ellipse at 30% 40%,#1a0533,#0d0d1a 60%,#000510);min-height:100vh;padding:60px 24px;display:flex;flex-direction:column;align-items:center}
h1{font-size:clamp(2rem,5vw,3.2rem);font-weight:700;color:#fff;text-align:center;margin-bottom:8px;letter-spacing:-.03em}
.sub{color:#6b7280;text-align:center;margin-bottom:60px;font-size:.9rem}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:32px;width:100%;max-width:1100px;perspective:2000px}
/* TILT CARD */
.tilt-wrap{perspective:1000px;width:100%}
.tilt-card{width:100%;border-radius:20px;position:relative;transform-style:preserve-3d;cursor:pointer;transition:transform .1s ease-out;will-change:transform}
/* glare layer */
.tilt-glare{position:absolute;inset:0;border-radius:20px;overflow:hidden;pointer-events:none;z-index:5}
.tilt-glare::after{content:'';position:absolute;width:100%;height:100%;background:radial-gradient(circle at var(--gx,50%) var(--gy,50%),rgba(255,255,255,.18),transparent 70%);opacity:0;transition:opacity .3s}
.tilt-wrap:hover .tilt-glare::after{opacity:1}
/* card content */
.tilt-inner{border-radius:20px;padding:32px;position:relative;overflow:hidden;height:340px;display:flex;flex-direction:column;justify-content:space-between}
/* Card 1 — Holographic */
.tc1 .tilt-inner{background:linear-gradient(135deg,#1a0533,#280648,#1a0533);border:1px solid rgba(167,139,250,.3)}
.tc1 .tilt-inner::before{content:'';position:absolute;inset:0;background:conic-gradient(from 0deg at 50% 50%,rgba(167,139,250,.08),rgba(236,72,153,.06),rgba(56,189,248,.08),rgba(167,139,250,.08));animation:trn16-holo 6s linear infinite}
@keyframes trn16-holo{to{transform:rotate(360deg)}}
/* Card 2 — Gold */
.tc2 .tilt-inner{background:linear-gradient(145deg,#1a1008,#2d1c06,#1a1008);border:1px solid rgba(251,191,36,.2)}
.tc2 .tilt-inner::before{content:'';position:absolute;inset:0;background:radial-gradient(circle at 30% 30%,rgba(251,191,36,.1),transparent 50%)}
/* Card 3 — Neon */
.tc3 .tilt-inner{background:linear-gradient(145deg,#001a14,#003020,#001a14);border:1px solid rgba(52,211,153,.25)}
.tc3 .tilt-inner::before{content:'';position:absolute;inset:0;background:radial-gradient(circle at 70% 70%,rgba(52,211,153,.08),transparent 50%)}
/* Card 4 — Chrome */
.tc4 .tilt-inner{background:linear-gradient(145deg,#111827,#1f2937,#111827);border:1px solid rgba(148,163,184,.15)}
.tc4 .tilt-inner::before{content:'';position:absolute;inset:0;background:linear-gradient(135deg,rgba(255,255,255,.04) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.04) 50%,rgba(255,255,255,.04) 75%,transparent 75%);background-size:20px 20px}
/* card elements */
.tc-badge{font-size:.65rem;font-weight:700;letter-spacing:.2em;text-transform:uppercase;padding:6px 12px;border-radius:20px;display:inline-flex;align-items:center;gap:6px;position:relative;z-index:2}
.tc1 .tc-badge{background:rgba(167,139,250,.15);color:#c4b5fd;border:1px solid rgba(167,139,250,.2)}
.tc2 .tc-badge{background:rgba(251,191,36,.12);color:#fde68a;border:1px solid rgba(251,191,36,.2)}
.tc3 .tc-badge{background:rgba(52,211,153,.12);color:#6ee7b7;border:1px solid rgba(52,211,153,.2)}
.tc4 .tc-badge{background:rgba(148,163,184,.1);color:#cbd5e1;border:1px solid rgba(148,163,184,.15)}
.tc-icon{font-size:3.5rem;display:block;position:relative;z-index:2;filter:drop-shadow(0 4px 16px rgba(0,0,0,.4))}
.tc-title{font-size:1.4rem;font-weight:700;color:#fff;margin-bottom:6px;position:relative;z-index:2}
.tc-desc{font-size:.82rem;color:rgba(255,255,255,.5);line-height:1.5;position:relative;z-index:2}
.tc-footer{display:flex;align-items:center;justify-content:space-between;position:relative;z-index:2}
.tc-action{font-size:.8rem;font-weight:600;color:var(--ac,#c4b5fd);display:flex;align-items:center;gap:6px}
.tc1{--ac:#c4b5fd}.tc2{--ac:#fde68a}.tc3{--ac:#6ee7b7}.tc4{--ac:#cbd5e1}
.tc-stat{font-size:.75rem;color:rgba(255,255,255,.35)}
/* parallax floating elements inside card */
.tc-float{position:absolute;border-radius:50%;pointer-events:none;z-index:1;transition:transform .15s ease-out} @import url('https://fonts.googleapis.com/css2?family=Clash+Display:wght@400;600;700&family=General+Sans:wght@300;400;500;600&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap');
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Outfit',sans-serif;background:radial-gradient(ellipse at 30% 40%,#1a0533,#0d0d1a 60%,#000510);min-height:100vh;padding:60px 24px;display:flex;flex-direction:column;align-items:center}
h1{font-size:clamp(2rem,5vw,3.2rem);font-weight:700;color:#fff;text-align:center;margin-bottom:8px;letter-spacing:-.03em}
.sub{color:#6b7280;text-align:center;margin-bottom:60px;font-size:.9rem}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:32px;width:100%;max-width:1100px;perspective:2000px}
/* TILT CARD */
.tilt-wrap{perspective:1000px;width:100%}
.tilt-card{width:100%;border-radius:20px;position:relative;transform-style:preserve-3d;cursor:pointer;transition:transform .1s ease-out;will-change:transform}
/* glare layer */
.tilt-glare{position:absolute;inset:0;border-radius:20px;overflow:hidden;pointer-events:none;z-index:5}
.tilt-glare::after{content:'';position:absolute;width:100%;height:100%;background:radial-gradient(circle at var(--gx,50%) var(--gy,50%),rgba(255,255,255,.18),transparent 70%);opacity:0;transition:opacity .3s}
.tilt-wrap:hover .tilt-glare::after{opacity:1}
/* card content */
.tilt-inner{border-radius:20px;padding:32px;position:relative;overflow:hidden;height:340px;display:flex;flex-direction:column;justify-content:space-between}
/* Card 1 — Holographic */
.tc1 .tilt-inner{background:linear-gradient(135deg,#1a0533,#280648,#1a0533);border:1px solid rgba(167,139,250,.3)}
.tc1 .tilt-inner::before{content:'';position:absolute;inset:0;background:conic-gradient(from 0deg at 50% 50%,rgba(167,139,250,.08),rgba(236,72,153,.06),rgba(56,189,248,.08),rgba(167,139,250,.08));animation:trn16-holo 6s linear infinite}
@keyframes trn16-holo{to{transform:rotate(360deg)}}
/* Card 2 — Gold */
.tc2 .tilt-inner{background:linear-gradient(145deg,#1a1008,#2d1c06,#1a1008);border:1px solid rgba(251,191,36,.2)}
.tc2 .tilt-inner::before{content:'';position:absolute;inset:0;background:radial-gradient(circle at 30% 30%,rgba(251,191,36,.1),transparent 50%)}
/* Card 3 — Neon */
.tc3 .tilt-inner{background:linear-gradient(145deg,#001a14,#003020,#001a14);border:1px solid rgba(52,211,153,.25)}
.tc3 .tilt-inner::before{content:'';position:absolute;inset:0;background:radial-gradient(circle at 70% 70%,rgba(52,211,153,.08),transparent 50%)}
/* Card 4 — Chrome */
.tc4 .tilt-inner{background:linear-gradient(145deg,#111827,#1f2937,#111827);border:1px solid rgba(148,163,184,.15)}
.tc4 .tilt-inner::before{content:'';position:absolute;inset:0;background:linear-gradient(135deg,rgba(255,255,255,.04) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.04) 50%,rgba(255,255,255,.04) 75%,transparent 75%);background-size:20px 20px}
/* card elements */
.tc-badge{font-size:.65rem;font-weight:700;letter-spacing:.2em;text-transform:uppercase;padding:6px 12px;border-radius:20px;display:inline-flex;align-items:center;gap:6px;position:relative;z-index:2}
.tc1 .tc-badge{background:rgba(167,139,250,.15);color:#c4b5fd;border:1px solid rgba(167,139,250,.2)}
.tc2 .tc-badge{background:rgba(251,191,36,.12);color:#fde68a;border:1px solid rgba(251,191,36,.2)}
.tc3 .tc-badge{background:rgba(52,211,153,.12);color:#6ee7b7;border:1px solid rgba(52,211,153,.2)}
.tc4 .tc-badge{background:rgba(148,163,184,.1);color:#cbd5e1;border:1px solid rgba(148,163,184,.15)}
.tc-icon{font-size:3.5rem;display:block;position:relative;z-index:2;filter:drop-shadow(0 4px 16px rgba(0,0,0,.4))}
.tc-title{font-size:1.4rem;font-weight:700;color:#fff;margin-bottom:6px;position:relative;z-index:2}
.tc-desc{font-size:.82rem;color:rgba(255,255,255,.5);line-height:1.5;position:relative;z-index:2}
.tc-footer{display:flex;align-items:center;justify-content:space-between;position:relative;z-index:2}
.tc-action{font-size:.8rem;font-weight:600;color:var(--ac,#c4b5fd);display:flex;align-items:center;gap:6px}
.tc1{--ac:#c4b5fd}.tc2{--ac:#fde68a}.tc3{--ac:#6ee7b7}.tc4{--ac:#cbd5e1}
.tc-stat{font-size:.75rem;color:rgba(255,255,255,.35)}
/* parallax floating elements inside card */
.tc-float{position:absolute;border-radius:50%;pointer-events:none;z-index:1;transition:transform .15s ease-out}document.querySelectorAll('.tilt-wrap').forEach(wrap => {
const card = wrap.querySelector('.tilt-card');
const glare = wrap.querySelector('.tilt-glare');
const floats = wrap.querySelectorAll('.tc-float');
const MAX_TILT = 18;
wrap.addEventListener('mousemove', e => {
const rect = wrap.getBoundingClientRect();
const x = (e.clientX - rect.left) / rect.width;
const y = (e.clientY - rect.top) / rect.height;
const rotY = (x - .5) * MAX_TILT * 2;
const rotX = (.5 - y) * MAX_TILT * 2;
card.style.transform = `rotateX(${rotX}deg) rotateY(${rotY}deg) scale(1.04)`;
glare.style.setProperty('--gx', (x * 100) + '%');
glare.style.setProperty('--gy', (y * 100) + '%');
glare.querySelector('::after');
// Parallax floats
floats.forEach(f => {
f.style.transform = `translate(${(x-.5)*20}px,${(y-.5)*20}px)`;
});
});
wrap.addEventListener('mouseleave', () => {
card.style.transform = 'rotateX(0) rotateY(0) scale(1)';
floats.forEach(f => { f.style.transform = ''; });
});
}); document.querySelectorAll('.tilt-wrap').forEach(wrap => {
const card = wrap.querySelector('.tilt-card');
const glare = wrap.querySelector('.tilt-glare');
const floats = wrap.querySelectorAll('.tc-float');
const MAX_TILT = 18;
wrap.addEventListener('mousemove', e => {
const rect = wrap.getBoundingClientRect();
const x = (e.clientX - rect.left) / rect.width;
const y = (e.clientY - rect.top) / rect.height;
const rotY = (x - .5) * MAX_TILT * 2;
const rotX = (.5 - y) * MAX_TILT * 2;
card.style.transform = `rotateX(${rotX}deg) rotateY(${rotY}deg) scale(1.04)`;
glare.style.setProperty('--gx', (x * 100) + '%');
glare.style.setProperty('--gy', (y * 100) + '%');
glare.querySelector('::after');
// Parallax floats
floats.forEach(f => {
f.style.transform = `translate(${(x-.5)*20}px,${(y-.5)*20}px)`;
});
});
wrap.addEventListener('mouseleave', () => {
card.style.transform = 'rotateX(0) rotateY(0) scale(1)';
floats.forEach(f => { f.style.transform = ''; });
});
});More from 22 CSS Transition Effects
Slide-In Animation on ScrollFade In Fade Out TransitionLoading Skeleton TransitionModal Open Close TransitionPage Transition EffectRipple Effect on ClickNumber Counter AnimationStaggered List AnimationCursor Trail EffectMagnetic Button EffectSplit Text Reveal TransitionProgress Bar Animation
View the full collection →