15 Tailwind CSS 3D tilt hover cards for D2C product spotlights, SaaS pricing rows, agency team and mascot cards, streaming music players, FinTech KPI dashboards, real-estate listings, and app-landing phone mockups — spanning parallax hover, glassmorphism and holographic foil, cursor-following border glow, spring physics, click-to-flip, and a zero-JavaScript :has() variant. Scoped under .ttc-NN for no-collision pasting, prefers-reduced-motion guarded, framework-agnostic.
Building a whole Tailwind app, not just this component?
You just browsed 15 Tailwind 3d tilt hover cards. Untitled UI Pro unlocks 5,000+ components and sections and 250+ page examples for React, styled with Tailwind CSS v4. One licence is a one-time $349 with lifetime updates; teams start at $999.
The D2C product spotlight in utilities: the sneaker floats at translate-z-[50px], the Add-to-Cart button rides higher at translate-z-[60px], and a radial glare chases the cursor. The whole depth stack is declared on the elements that own it, and the port adds a working colourway picker — three real radios that re-hue the product with has-[[value=volt]:checked]:[--hue:110deg], no extra JS.
A frosted-glass team card for agency About pages: real backdrop-blur-[20px] over an oklch aurora, a gradient hairline drawn with the padding-box/border-box trick, a spinning conic avatar ring animated through @property, and three depth planes that separate as the card tilts ±10°. Tailwind writes the -webkit-backdrop-filter prefix for you.
A three-tier SaaS pricing row where every card tilts toward the cursor and the featured Pro tier adds a scale boost and a violet glow. The port finishes what the CSS original only promised: a working monthly/annual toggle whose prices swap through group-data-annual/root: variants, with tabular-nums keeping the digits rock-steady.
Trading-card-grade holo in utilities: a six-stop oklch conic-gradient foil travels opposite the cursor under mix-blend-color-dodge, a specular stripe rakes across on mix-blend-overlay, and the card banks a dramatic ±20°. New in the port: touch screens get a slow idle foil sweep via pointer-coarse:animate-ttc04-sweep, so phones see the holo too.
The scroll-stopping agency trick: a mascot whose head rises OUTSIDE the card, floating at translate-z-[45px] and lifting to 70px on hover while the card tilts beneath it. The port gives the character a personality upgrade — pupils that follow the cursor and an idle blink — using the same custom-property bridge that drives the tilt.
The dev-tool feature grid: near-black cards whose 1px border lights up in a radial glow that follows the cursor — and bleeds onto a neighbour's edge before the pointer arrives — plus a whisper of tilt (±5°). The ring is one before: layer masked to the border with [mask-composite:exclude]; each card now owns its own accent via [--color-ttc06-edge:…].
Newsletter
Enjoying these demos? Get new ones by email.
A short email when a new collection ships. Unsubscribe any time.
A streaming-app album card driven by a requestAnimationFrame spring that overshoots and settles like a physical object. The port makes the player actually play: the play button is a real aria-pressed toggle, and group-has-[[data-play][aria-pressed=true]]/card: spins the vinyl, slides it out, starts the equaliser and runs the progress bar — all in CSS.
An editorial card that respects reading: tilt capped at ±4.5° so the headline never smears, a cover that eases to scale-104, and an author row that slides open with the grid-rows-[0fr] → grid-rows-[1fr] trick. The port fixes the original's biggest miss: the reveal now also opens on keyboard focus (group-focus-visible/link:) and is always open on touch.
An event-promo card whose neon reacts physically: the magenta and cyan glows are offset FROM the tilt, so the side the card banks away from throws a longer glow — like a sign swinging in front of a wall. One arbitrary [box-shadow:var(--gx)_var(--gy)_…] carries both throws; scanlines and a soft, non-strobing tube flicker finish the Night City read.
A FinTech KPI widget with enterprise restraint: perspective(1600px), ±4° tilt, a 6px lift with a deepening shadow, and a CSS-only sparkline of flex bars that stagger-grow when the tilt arms. The port styles all thirteen bars from the parent with v4's *: child variant, and adds hover tooltips read straight from each bar's data-v via *:after:content-[attr(data-v)].
A luxury listing built on absence: white space, one hairline rule, Instrument Serif numerals — and a photo that lives in grayscale until hover develops the colour over 700ms while the card tilts a fluid ±7°. The port fixes the structure: the card is no longer one giant link, so a real Save toggle can sit on the photo, and the address is a stretched link.
Tilt and flip in one transform: the card follows the cursor, and a click (or Enter/Space) swings it 180° to reveal contact details — and it keeps tilting while flipped. Flip and tilt compose in one rotateY(calc(var(--flip)_+_var(--ry))). The port fixes a real bug: the hidden face is now inert, so its buttons can no longer be tabbed to while invisible.
An app-landing hero card: a CSS-drawn phone rests at a 3D angle and straightens toward you as the cursor approaches, while rating and download badges bob in front of it and a specular streak sweeps the glass. The port fixes a flattening bug — the phone now carries its own perspective(900px), because the card's overflow-hidden was collapsing its rotation to a squash — and adds a real download CTA.
An EdTech course card where progress is the hero: a 68%-complete pill floats highest at translate-z-[40px], the progress fill carries a glint that slides with the cursor via --mx, and module metadata sits calmly lower. Depth encodes hierarchy. The port adds a labelled progress row (module 9 of 12) with a proper aria-valuetext.
Newsletter
Enjoying these demos? Get new ones by email.
A short email when a new collection ships. Unsubscribe any time.
Zero JavaScript, zero listeners: nine invisible hover zones tile the card, and has-[[data-z=c]:hover]:[--rx:var(--tx)] maps whichever zone the cursor occupies to a tilt pose. Eased transitions blend the nine poses into motion that feels continuous. New in the port: the glare glides between zones because --ttc15-mx/--ttc15-my are registered with @property and transitioned.
FAQ
Frequently asked questions
How does the 3D tilt actually work using only Tailwind utilities?
Every card sets a perspective on the outer wrapper and applies rotate-x and rotate-y to an inner element as the cursor moves. The wrapper's perspective is the viewing distance — a small value like perspective(800px) exaggerates the tilt, while the KPI card's perspective(1600px) keeps it restrained. A pointer handler reads the cursor position relative to the card, maps it to a rotation range (say ±10°), and writes those degrees onto the inner element. That element also needs transform-style: preserve-3d (Tailwind's transform-3d) so any layers inside keep their own depth. Without perspective on an ancestor, rotate-x and rotate-y still apply but render as a flat 2D skew — the tilt only reads as real 3D once perspective establishes a vanishing point for the whole card.
Why do my parallax layers look flat and translate-z does nothing?
This is the number one 3D bug. Layers lifted with translate-z-[50px] — the floating sneaker in the product card, the pop-out mascot head, the 68% progress pill — only separate in depth if every ancestor between them and the perspective root carries transform-style: preserve-3d. The moment one wrapper uses the default flat, it flattens all descendants onto its own plane and every translate-z collapses to zero visible offset. A second cause: putting the perspective and the transform on the same element. Perspective must live on the parent; the tilt and the raised layers live on children. Also check you haven't set overflow-hidden on the tilting element when a layer needs to float past its edge — the pop-out character card deliberately leaves overflow visible so the head can rise above the top border.
How does the card follow the mouse without a tilt library like Tilt.js?
There is no library here — a small pointer handler does the maths. On pointermove it takes the cursor x/y, subtracts the card's centre, divides by half the card's width and height to get a −1..1 ratio, then multiplies by the maximum angle. Those two numbers are written back as inline transform values or CSS custom properties that the Tailwind classes reference. The glow cards go further: the mouse-following border stores the raw cursor coordinates and feeds them into a radial-gradient centre, so the light sits under the pointer instead of tilting. On pointerleave every handler resets the values to zero so the card eases back to rest. Keep the handler cheap — read the card's size once on pointerenter and cache it, rather than measuring layout on every single move — or the tilt stutters on lower-end devices.
Can I build a 3D tilt card with no JavaScript at all?
Yes — the final demo does it with zero listeners. It tiles the card with nine invisible hover zones in a 3×3 grid, each carrying a data-z marker for its position. A has-[[data-z=c]:hover] style on the card matches when a given zone is hovered and applies the matching rotate-x/rotate-y pair for that corner or edge. Because it is pure :has(), the tilt snaps between nine discrete angles rather than tracking the cursor continuously — smooth enough with a transition, but not pixel-precise like the JavaScript versions. The tradeoff is honesty: it works with scripting disabled, has no handler cost, and can never leak an event listener. Reach for it when you want the effect on a static card and don't need the cursor-exact follow that a pointermove handler gives you.
Are these 3D tilt cards keyboard accessible?
The interactive one to get right is the flip card. It flips on click and on Enter or Space, which means the trigger must be focusable — the cleanest route is to make the flip control a real <button> so focus, activation and the focus ring all come for free, rather than bolting tabindex and a key handler onto a <div>. Tilt-only cards that just react to the pointer are decorative: a keyboard user never triggers the tilt, and that is fine as long as the underlying content — the Add-to-Cart control, the pricing link, the blog headline — is a normal focusable element that works with no hover. Watch the pop-out and holographic cards: if a raised layer sits over interactive content, set pointer-events-none on the decorative layer so it never swallows a click or blocks focus reaching the button beneath.
How do I respect prefers-reduced-motion on these hover effects?
Tilt is vestibular motion, so gate it. Wrap the transition and any continuous animation — the holographic foil sweep, the neon pulse, the spring settle — in motion-safe variants, or add a @media (prefers-reduced-motion: reduce) block that drops the rotation to zero and removes the transition. The card should still show its full rest state and all its content; only the movement goes away. This matters most on cards where depth is load-bearing decoration rather than information: the character pop-out, the cyberpunk glow, the holo foil. The dashboard KPI and course-progress cards already lean conservative — ±4° tilt, a 6px lift — which reads as a gentle hover more than motion, but you should still honour the reduce query. A subtle tilt is still motion to someone who explicitly asked for none.
Why does the tilt feel janky, and what is the spring physics card doing differently?
Jank almost always traces to two things: animating a property that isn't compositor-friendly, or doing layout work inside pointermove. Keep everything on transform and opacity — the tilt is rotate-x/rotate-y, the lift is a translate, never top or margin. Read the card's size once on pointerenter, cache it, and only compute rotations on move. The music-player card adds a requestAnimationFrame spring: instead of snapping the rotation straight to the target angle each frame, it eases the current angle toward the target with a stiffness and damping factor, so the card overshoots slightly and settles — the physical feel a plain CSS transition can't produce. Cancel the rAF loop on pointerleave once it reaches rest, or it keeps ticking idle in the background and burns frames.
When should I not use a 3D tilt hover card?
Skip it when hover is the wrong interaction or the motion fights the content. On touch devices there is no hover at all, so a pointer-driven tilt does nothing — ship a flat, complete rest state and treat the tilt as progressive enhancement, never a requirement to read or tap anything. Avoid steep tilt on text-heavy cards: the blog demo caps rotation at ±4.5° precisely because a sharper angle smears the headline and hurts reading. Don't stack the loud variants either — a grid of holographic-foil or neon cards all tilting at once is visual noise and a lot of per-frame work, so reserve the effect for one hero card or a short feature row. And if a card's whole job is to be clicked fast — a dense pricing table, a KPI dashboard — keep the tilt tiny or drop it. Motion that delays the eye from the number is a cost, not a feature.