Home / Snippets / Animation & Motion /
Tilt/perspective
A card that tilts in 3D on hover using perspective() and rotateX/rotateY — CSS only.
Quick implementation
.tilt-card {
transition: transform 0.4s ease;
}
.tilt-card:hover {
transform: perspective(600px) rotateX(5deg) rotateY(-5deg);
}
@media (prefers-reduced-motion: reduce) {
.tilt-card { transition: none; }
.tilt-card:hover { transform: none; }
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer building a CSS interaction library.
Goal: A tilt/perspective hover effect — a card rotates in 3D on hover using CSS transforms only, no JavaScript.
Technical constraints:
- Use transform: perspective(600px) rotateX(Xdeg) rotateY(Ydeg) on :hover.
- Apply transition: transform 0.4s ease on the card element so it animates in and out.
- perspective() must be part of the transform function list, not a separate perspective property, to avoid stacking-context side effects.
- Use oklch() for background and border colors, not hex or rgba().
- Include @media (prefers-reduced-motion: reduce) to reset the transform and remove the transition.
Framework variant (pick one):
A) Vanilla CSS — single class with customizable rotation degrees via CSS custom properties.
B) React component — accept rotateX and rotateY as numeric props with sensible defaults (5deg / -5deg).
Edge cases to handle:
- Reset smoothly to identity transform on mouse-out (the transition handles this automatically).
- Avoid using transform: perspective() on a parent element — that approach changes child stacking.
- Do not combine with will-change: transform unless measuring a real performance bottleneck.
- Ensure the card content (text, images) does not overflow when tilted — use overflow: hidden if needed.
Return CSS.
Why this matters in 2026
The tilt/perspective effect adds tactile depth to feature cards, product images, and testimonial blocks without any JavaScript dependency. A static card becomes a 3D object the user feels they can interact with, increasing perceived quality. Done in CSS, it degrades gracefully in environments where transforms are unavailable and respects motion preferences automatically.
The logic
perspective(600px) in the transform chain sets the eye distance for this element only, without creating a perspective context that would affect sibling elements. rotateX(5deg) tips the top of the card away and rotateY(-5deg) tips the right side toward the viewer, producing a top-left lifted look. The transition: transform 0.4s ease on the base state means the card both enters and exits the tilt smoothly — CSS automatically reverses the transition on :not(:hover).
Accessibility & performance
@media (prefers-reduced-motion: reduce) removes both the transition and the hover transform entirely, leaving the card flat. Users who find rotational movement disorienting see no motion at all. transform is compositor-only — no layout recalculations occur. Avoid adding will-change: transform speculatively; it promotes the element to its own compositor layer before it is needed and wastes GPU memory on pages with many cards.