17 / 33
All 33 in 33 Tailwind CSS Card Hover Effects
- 01Tailwind 3D Tilt & Parallax Card with Depth Layers
- 02Tailwind Glowing Gradient & Glassmorphic Border Card
- 03Tailwind Image Zoom Card with Slide-Up Content Reveal
- 04Tailwind 3D Flip Card (Front to Back) with backface-visibility
- 05Tailwind Sibling De-emphasis Pricing Grid with has-hover
- 06Tailwind Minimalist Elevation Card with Layered Dynamic Shadows
- 07Tailwind Elastic Lift Card with Spring Cubic-Bezier
- 08Tailwind Animated Conic Gradient Border Card with @property
- 09Tailwind Stacked Layer Reveal Card (Fanned Risograph Deck)
- 10Tailwind Holographic Foil Shimmer Card with mix-blend-mode
- 11Tailwind Curtain Reveal Card (Parting Velvet Halves)
- 12Tailwind Corner Peel Card with clip-path Triangles
- 13Tailwind Neon Sign Card with Layered Text-Shadow Glow
- 14Tailwind CRT Scanline Terminal Card with Sweeping Beam
- 15Tailwind Depth Parallax Landscape Card with Layer Multipliers
- 16Tailwind Cursor Spotlight Card with Masked Border Highlight
- 17Tailwind 3D Tilt Product Card with Specular Glare
- 18Tailwind Slide-Up Panel Card with Peek Header Swap
- 19Tailwind Credit Card Flip with Magnetic Strip & CVV
- 20Tailwind RGB Channel-Split Glitch Card
- 21Tailwind Rotating Conic Aura Card with Blurred Gradient Bloom
- 22Tailwind Blob-to-Rectangle Border Morph Card
- 23Tailwind Magnetic Float Orb Card with Pointer Attraction
- 24Tailwind Typewriter Reveal Card with Steps Animation & Caret
- 25Tailwind Magazine Overlay Slide Card (Full-Face Panel Takeover)
- 26Tailwind Breathing Film Grain Card with SVG Turbulence Noise
- 27Tailwind Frosted Glass Intensify Card with Deepening Backdrop Blur
- 28Tailwind Blueprint Reveal Card with Circular clip-path Wipe
- 29Tailwind Cursor-Anchored Shockwave Ripple Card
- 30Tailwind Color-Burn Ignition Card with Grayscale-to-Fire Hover
- 31Tailwind Prismatic Light Sweep Card with Screen Blend Bar
- 32Tailwind Book Cover Open Card with Hinged 3D Rotation
- 33Tailwind Drifting Aurora Ribbons Card with Blurred Gradient Bands
Tailwind 3D Tilt Product Card with Specular Glare
The simpler cousin of demo 01: one flat surface that leans toward the cursor, a specular glare that tracks the pointer, and text pushed onto four translateZ planes so the type floats above the face. Fewer moving parts, and the whole thing is one 20-line handler.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tch-17 w-full min-h-svh grid place-items-center bg-[radial-gradient(circle_at_70%_30%,#2a1f4d,#0d0a1a_70%)] font-tch17-sans p-8 [perspective:1100px]">
<article data-tch17="root" tabindex="0" class="group relative w-[330px] h-[440px] rounded-3xl cursor-pointer outline-none transform-3d bg-[linear-gradient(150deg,#3a2b6e,#18122e)] border border-white/8 shadow-[0_25px_50px_rgb(0_0_0/0.5)] transition-transform duration-100 ease-out focus-visible:outline-3 focus-visible:outline-tch17-acc focus-visible:outline-offset-4 motion-reduce:transition-none">
<div class="absolute inset-0 z-5 rounded-[inherit] pointer-events-none opacity-0 transition-opacity duration-300 bg-[radial-gradient(circle_at_var(--tch17-gx,50%)_var(--tch17-gy,50%),rgb(255_255_255/0.28),transparent_45%)] group-hover:opacity-100"></div>
<div class="h-full p-[2.4rem] flex flex-col justify-between text-tch17-ink">
<span class="self-start text-[0.7rem] tracking-[0.18em] uppercase px-3.5 py-1.5 border border-white/25 rounded-full text-tch17-mut [transform:translateZ(60px)]">Limited Drop</span>
<h2 class="font-tch17-display font-bold text-[2.8rem] leading-[0.95] [transform:translateZ(80px)]">Nimbus<br>Hi-Tops</h2>
<p class="text-[0.85rem] leading-[1.6] text-tch17-body [transform:translateZ(40px)]">Float-foam midsole and an iridescent upper that shifts as it turns in the light.</p>
<span class="font-tch17-display font-semibold text-[1.6rem] text-tch17-acc [transform:translateZ(70px)]">$189</span>
</div>
</article>
</section><section class="tch-17 w-full min-h-svh grid place-items-center bg-[radial-gradient(circle_at_70%_30%,#2a1f4d,#0d0a1a_70%)] font-tch17-sans p-8 [perspective:1100px]">
<article data-tch17="root" tabindex="0" class="group relative w-[330px] h-[440px] rounded-3xl cursor-pointer outline-none transform-3d bg-[linear-gradient(150deg,#3a2b6e,#18122e)] border border-white/8 shadow-[0_25px_50px_rgb(0_0_0/0.5)] transition-transform duration-100 ease-out focus-visible:outline-3 focus-visible:outline-tch17-acc focus-visible:outline-offset-4 motion-reduce:transition-none">
<div class="absolute inset-0 z-5 rounded-[inherit] pointer-events-none opacity-0 transition-opacity duration-300 bg-[radial-gradient(circle_at_var(--tch17-gx,50%)_var(--tch17-gy,50%),rgb(255_255_255/0.28),transparent_45%)] group-hover:opacity-100"></div>
<div class="h-full p-[2.4rem] flex flex-col justify-between text-tch17-ink">
<span class="self-start text-[0.7rem] tracking-[0.18em] uppercase px-3.5 py-1.5 border border-white/25 rounded-full text-tch17-mut [transform:translateZ(60px)]">Limited Drop</span>
<h2 class="font-tch17-display font-bold text-[2.8rem] leading-[0.95] [transform:translateZ(80px)]">Nimbus<br>Hi-Tops</h2>
<p class="text-[0.85rem] leading-[1.6] text-tch17-body [transform:translateZ(40px)]">Float-foam midsole and an iridescent upper that shifts as it turns in the light.</p>
<span class="font-tch17-display font-semibold text-[1.6rem] text-tch17-acc [transform:translateZ(70px)]">$189</span>
</div>
</article>
</section>@import "tailwindcss";
@theme {
--color-tch17-ink: #ede9ff;
--color-tch17-ink: oklch(0.94 0.02 285);
--color-tch17-body: #b3a9d6;
--color-tch17-body: oklch(0.75 0.05 290);
--color-tch17-mut: #c5b8ff;
--color-tch17-mut: oklch(0.82 0.08 290);
--color-tch17-acc: #9d7bff;
--color-tch17-acc: oklch(0.68 0.19 290);
--font-tch17-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tch17-display: 'Syne', system-ui, sans-serif;
}
.tch-17 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tch17-ink: #ede9ff;
--color-tch17-ink: oklch(0.94 0.02 285);
--color-tch17-body: #b3a9d6;
--color-tch17-body: oklch(0.75 0.05 290);
--color-tch17-mut: #c5b8ff;
--color-tch17-mut: oklch(0.82 0.08 290);
--color-tch17-acc: #9d7bff;
--color-tch17-acc: oklch(0.68 0.19 290);
--font-tch17-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tch17-display: 'Syne', system-ui, sans-serif;
}
.tch-17 {
width: 100%;
min-height: 100svh;
}(() => {
const root = document.querySelector('.tch-17');
if (!root) return;
const card = root.querySelector('[data-tch17="root"]');
if (!card) return;
if (!matchMedia('(hover: hover) and (pointer: fine)').matches) return;
if (matchMedia('(prefers-reduced-motion: reduce)').matches) return;
let frame = 0;
card.addEventListener('mousemove', (e) => {
if (frame) return;
frame = requestAnimationFrame(() => {
frame = 0;
const r = card.getBoundingClientRect();
const px = (e.clientX - r.left) / r.width;
const py = (e.clientY - r.top) / r.height;
card.style.transform = 'rotateY(' + ((px - 0.5) * 20) + 'deg) rotateX(' + ((0.5 - py) * 20) + 'deg)';
card.style.setProperty('--tch17-gx', '' + (px * 100) + '%');
card.style.setProperty('--tch17-gy', '' + (py * 100) + '%');
});
});
card.addEventListener('mouseleave', () => {
card.style.transform = 'rotateY(0deg) rotateX(0deg)';
});
})();(() => {
const root = document.querySelector('.tch-17');
if (!root) return;
const card = root.querySelector('[data-tch17="root"]');
if (!card) return;
if (!matchMedia('(hover: hover) and (pointer: fine)').matches) return;
if (matchMedia('(prefers-reduced-motion: reduce)').matches) return;
let frame = 0;
card.addEventListener('mousemove', (e) => {
if (frame) return;
frame = requestAnimationFrame(() => {
frame = 0;
const r = card.getBoundingClientRect();
const px = (e.clientX - r.left) / r.width;
const py = (e.clientY - r.top) / r.height;
card.style.transform = 'rotateY(' + ((px - 0.5) * 20) + 'deg) rotateX(' + ((0.5 - py) * 20) + 'deg)';
card.style.setProperty('--tch17-gx', '' + (px * 100) + '%');
card.style.setProperty('--tch17-gy', '' + (py * 100) + '%');
});
});
card.addEventListener('mouseleave', () => {
card.style.transform = 'rotateY(0deg) rotateX(0deg)';
});
})();Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tch17-ink: #ede9ff;
--color-tch17-ink: oklch(0.94 0.02 285);
--color-tch17-body: #b3a9d6;
--color-tch17-body: oklch(0.75 0.05 290);
--color-tch17-mut: #c5b8ff;
--color-tch17-mut: oklch(0.82 0.08 290);
--color-tch17-acc: #9d7bff;
--color-tch17-acc: oklch(0.68 0.19 290);
--font-tch17-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tch17-display: 'Syne', system-ui, sans-serif;
}
.tch-17 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tch17-ink: #ede9ff;
--color-tch17-ink: oklch(0.94 0.02 285);
--color-tch17-body: #b3a9d6;
--color-tch17-body: oklch(0.75 0.05 290);
--color-tch17-mut: #c5b8ff;
--color-tch17-mut: oklch(0.82 0.08 290);
--color-tch17-acc: #9d7bff;
--color-tch17-acc: oklch(0.68 0.19 290);
--font-tch17-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tch17-display: 'Syne', system-ui, sans-serif;
}
.tch-17 {
width: 100%;
min-height: 100svh;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Syne:wght@600;700&family=Space+Grotesk:wght@400;500&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Syne:wght@600;700&family=Space+Grotesk:wght@400;500&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Depth on the content elements instead of on dedicated layer divs is the port's structural simplification — four arbitrary
translateZproperties replace four wrapper elements. - The original used Clash Display via a second, unreliable font CDN. Swapped to Syne from Google Fonts: same geometric-display register, one request, no third-party dependency.
- UI change from the CSS original: focusable card with a ring, rAF throttling, and guards that skip the listener on touch and under reduced motion.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind 3D Tilt Product Card with Specular Glare
Source: https://codefronts.com/motion/tailwind-css-card-hover-effects/tailwind-3d-tilt-product-card-specular-glare/
The simpler cousin of demo 01: one flat surface that leans toward the cursor, a specular glare that tracks the pointer, and text pushed onto four translateZ planes so the type floats above the face. Fewer moving parts, and the whole thing is one 20-line handler.
## HTML
```html
<section class="tch-17 w-full min-h-svh grid place-items-center bg-[radial-gradient(circle_at_70%_30%,#2a1f4d,#0d0a1a_70%)] font-tch17-sans p-8 [perspective:1100px]">
<article data-tch17="root" tabindex="0" class="group relative w-[330px] h-[440px] rounded-3xl cursor-pointer outline-none transform-3d bg-[linear-gradient(150deg,#3a2b6e,#18122e)] border border-white/8 shadow-[0_25px_50px_rgb(0_0_0/0.5)] transition-transform duration-100 ease-out focus-visible:outline-3 focus-visible:outline-tch17-acc focus-visible:outline-offset-4 motion-reduce:transition-none">
<div class="absolute inset-0 z-5 rounded-[inherit] pointer-events-none opacity-0 transition-opacity duration-300 bg-[radial-gradient(circle_at_var(--tch17-gx,50%)_var(--tch17-gy,50%),rgb(255_255_255/0.28),transparent_45%)] group-hover:opacity-100"></div>
<div class="h-full p-[2.4rem] flex flex-col justify-between text-tch17-ink">
<span class="self-start text-[0.7rem] tracking-[0.18em] uppercase px-3.5 py-1.5 border border-white/25 rounded-full text-tch17-mut [transform:translateZ(60px)]">Limited Drop</span>
<h2 class="font-tch17-display font-bold text-[2.8rem] leading-[0.95] [transform:translateZ(80px)]">Nimbus<br>Hi-Tops</h2>
<p class="text-[0.85rem] leading-[1.6] text-tch17-body [transform:translateZ(40px)]">Float-foam midsole and an iridescent upper that shifts as it turns in the light.</p>
<span class="font-tch17-display font-semibold text-[1.6rem] text-tch17-acc [transform:translateZ(70px)]">$189</span>
</div>
</article>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tch17-ink: #ede9ff;
--color-tch17-ink: oklch(0.94 0.02 285);
--color-tch17-body: #b3a9d6;
--color-tch17-body: oklch(0.75 0.05 290);
--color-tch17-mut: #c5b8ff;
--color-tch17-mut: oklch(0.82 0.08 290);
--color-tch17-acc: #9d7bff;
--color-tch17-acc: oklch(0.68 0.19 290);
--font-tch17-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tch17-display: 'Syne', system-ui, sans-serif;
}
.tch-17 {
width: 100%;
min-height: 100svh;
}
```
## JavaScript
```js
(() => {
const root = document.querySelector('.tch-17');
if (!root) return;
const card = root.querySelector('[data-tch17="root"]');
if (!card) return;
if (!matchMedia('(hover: hover) and (pointer: fine)').matches) return;
if (matchMedia('(prefers-reduced-motion: reduce)').matches) return;
let frame = 0;
card.addEventListener('mousemove', (e) => {
if (frame) return;
frame = requestAnimationFrame(() => {
frame = 0;
const r = card.getBoundingClientRect();
const px = (e.clientX - r.left) / r.width;
const py = (e.clientY - r.top) / r.height;
card.style.transform = 'rotateY(' + ((px - 0.5) * 20) + 'deg) rotateX(' + ((0.5 - py) * 20) + 'deg)';
card.style.setProperty('--tch17-gx', '' + (px * 100) + '%');
card.style.setProperty('--tch17-gy', '' + (py * 100) + '%');
});
});
card.addEventListener('mouseleave', () => {
card.style.transform = 'rotateY(0deg) rotateX(0deg)';
});
})();
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind 3D Tilt Product Card with Specular Glare
Source: https://codefronts.com/motion/tailwind-css-card-hover-effects/tailwind-3d-tilt-product-card-specular-glare/
The simpler cousin of demo 01: one flat surface that leans toward the cursor, a specular glare that tracks the pointer, and text pushed onto four translateZ planes so the type floats above the face. Fewer moving parts, and the whole thing is one 20-line handler.
## HTML
```html
<section class="tch-17 w-full min-h-svh grid place-items-center bg-[radial-gradient(circle_at_70%_30%,#2a1f4d,#0d0a1a_70%)] font-tch17-sans p-8 [perspective:1100px]">
<article data-tch17="root" tabindex="0" class="group relative w-[330px] h-[440px] rounded-3xl cursor-pointer outline-none transform-3d bg-[linear-gradient(150deg,#3a2b6e,#18122e)] border border-white/8 shadow-[0_25px_50px_rgb(0_0_0/0.5)] transition-transform duration-100 ease-out focus-visible:outline-3 focus-visible:outline-tch17-acc focus-visible:outline-offset-4 motion-reduce:transition-none">
<div class="absolute inset-0 z-5 rounded-[inherit] pointer-events-none opacity-0 transition-opacity duration-300 bg-[radial-gradient(circle_at_var(--tch17-gx,50%)_var(--tch17-gy,50%),rgb(255_255_255/0.28),transparent_45%)] group-hover:opacity-100"></div>
<div class="h-full p-[2.4rem] flex flex-col justify-between text-tch17-ink">
<span class="self-start text-[0.7rem] tracking-[0.18em] uppercase px-3.5 py-1.5 border border-white/25 rounded-full text-tch17-mut [transform:translateZ(60px)]">Limited Drop</span>
<h2 class="font-tch17-display font-bold text-[2.8rem] leading-[0.95] [transform:translateZ(80px)]">Nimbus<br>Hi-Tops</h2>
<p class="text-[0.85rem] leading-[1.6] text-tch17-body [transform:translateZ(40px)]">Float-foam midsole and an iridescent upper that shifts as it turns in the light.</p>
<span class="font-tch17-display font-semibold text-[1.6rem] text-tch17-acc [transform:translateZ(70px)]">$189</span>
</div>
</article>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tch17-ink: #ede9ff;
--color-tch17-ink: oklch(0.94 0.02 285);
--color-tch17-body: #b3a9d6;
--color-tch17-body: oklch(0.75 0.05 290);
--color-tch17-mut: #c5b8ff;
--color-tch17-mut: oklch(0.82 0.08 290);
--color-tch17-acc: #9d7bff;
--color-tch17-acc: oklch(0.68 0.19 290);
--font-tch17-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tch17-display: 'Syne', system-ui, sans-serif;
}
.tch-17 {
width: 100%;
min-height: 100svh;
}
```
## JavaScript
```js
(() => {
const root = document.querySelector('.tch-17');
if (!root) return;
const card = root.querySelector('[data-tch17="root"]');
if (!card) return;
if (!matchMedia('(hover: hover) and (pointer: fine)').matches) return;
if (matchMedia('(prefers-reduced-motion: reduce)').matches) return;
let frame = 0;
card.addEventListener('mousemove', (e) => {
if (frame) return;
frame = requestAnimationFrame(() => {
frame = 0;
const r = card.getBoundingClientRect();
const px = (e.clientX - r.left) / r.width;
const py = (e.clientY - r.top) / r.height;
card.style.transform = 'rotateY(' + ((px - 0.5) * 20) + 'deg) rotateX(' + ((0.5 - py) * 20) + 'deg)';
card.style.setProperty('--tch17-gx', '' + (px * 100) + '%');
card.style.setProperty('--tch17-gy', '' + (py * 100) + '%');
});
});
card.addEventListener('mouseleave', () => {
card.style.transform = 'rotateY(0deg) rotateX(0deg)';
});
})();
```How this works
No layer divs, just depth on the content. Demo 01 stacks background planes; this one pushes the existing text elements to 40px, 60px, 70px and 80px. Same parallax cue, a quarter of the markup — which is why this is the version to reach for on a product grid.
The tilt is a 20° range. The handler maps the pointer's normalised position to rotateY/rotateX, wider than demo 01's 18° because a flat surface can take more lean before it looks broken.
The glare sells the material. A white radial at the pointer, at 0.28 peak opacity, is what turns a leaning rectangle into something with a surface.
Make it yours
- Tilt range is the
20multiplier — 8 for subtle, 26 for showroom. - Depth spread: keep the ordering (title highest, copy lowest) or the hierarchy inverts.
- Swap the glare radial for a narrow linear gradient to get a sheen band instead of a hotspot.
Gotchas — read before shipping
[perspective:1100px]on the stage, not the card.- The glare needs
pointer-events-noneor it intercepts the clicks the card wants. - Reset the transform on
mouseleave— without it the card stays frozen at its last angle, which looks like a bug rather than a state. - Tilt is not a focus indicator. The card carries a real ring of its own.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
3D transforms and custom properties are universally supported; the floor is Tailwind v4's generated sheet.