Tilt (3D Hover)
Mouse-aware 3D perspective tilt. The tilt= attr activates the effect.
CSS handles the transform; a tiny runtime script feeds --aura-tilt-x/y
on mousemove. Respects prefers-reduced-motion.
Basic tilt
Hover the cards
Default tilt
tilt (8°)
Gentle tilt
tilt="5" (5°)
Strong tilt
tilt="lg" (15°)
<div tilt>…</div> <!-- default: 8° --> <div tilt="5">…</div> <!-- 5° max --> <div tilt="sm">…</div> <!-- 5° preset --> <div tilt="lg">…</div> <!-- 15° preset --> <div tilt="xl">…</div> <!-- 25° preset (dramatic) -->
With shine overlay
tilt-shine — follows mouse position
Shine effect
Move mouse over me
Stronger tilt
tilt="10" + shine
<div tilt tilt-shine gradient="brand">…</div> <div tilt="10" tilt-shine>…</div>
Scale on hover
tilt-scale — subtle grow effect
Tilt + scale
Grows 4% on hover
<div tilt tilt-scale>Grows slightly on hover</div>
CSS-only fallback
tilt-css — no JS, fixed angle on hover
CSS-only tilt
Pure CSS hover state
<!-- No JS, just a CSS :hover transform --> <div tilt tilt-css style="--aura-tilt-max-deg:8deg">…</div>
How it works
The CSS sets a 3D perspective transform reading two CSS custom properties.
The runtime listens to mousemove and writes those vars per-frame:
/* CSS side (tilt.css) */
[tilt] {
transform: perspective(800px)
rotateX(var(--aura-tilt-x, 0deg))
rotateY(var(--aura-tilt-y, 0deg));
}
/* Runtime feeds the vars on mousemove */
el.style.setProperty('--aura-tilt-x', `${rotX}deg`)
el.style.setProperty('--aura-tilt-y', `${rotY}deg`)
/* Tokens */
--aura-tilt-perspective: 800px
--aura-tilt-duration: 150ms