14 / 30
All 30 in 30 Tailwind CSS Hover Effects
- 01Tailwind Underline Draw Hover Effect
- 02Tailwind Text Glitch Hover Effect
- 03Tailwind Letter Spacing Expand Hover Effect
- 04Tailwind Gradient Text Reveal Hover Effect
- 05Tailwind Split Text Hover Effect
- 06Tailwind Neon Glow Text Hover Effect
- 07Tailwind Magnetic Liquid Button Hover Effect
- 08Tailwind Border Draw Hover Effect
- 09Tailwind Shimmer Shine Button Hover Effect
- 10Tailwind Fill Wipe Button Hover Effect
- 11Tailwind 3D Press Button Hover Effect
- 12Tailwind Ripple Button Hover Effect
- 13Tailwind 3D Tilt Card Hover Effect
- 14Tailwind Card Flip Hover Effect
- 15Tailwind Glassmorphism Card Hover Effect
- 16Tailwind Spotlight Card Hover Effect
- 17Tailwind Slide Reveal Card Hover Effect
- 18Tailwind Stack Lift Card Hover Effect
- 19Tailwind Zoom Pan Image Hover Effect
- 20Tailwind Color Channel Split Hover Effect
- 21Tailwind Duotone Image Hover Effect
- 22Tailwind Curtain Reveal Image Hover Effect
- 23Tailwind Ken Burns Image Hover Effect
- 24Tailwind Image Tilt Depth Hover Effect
- 25Tailwind Underline Slide Nav Hover Effect
- 26Tailwind Highlight Fill Nav Hover Effect
- 27Tailwind Strikethrough Hover Link Effect
- 28Tailwind Inline Word Swap Hover Effect
- 29Tailwind Dot Trail Cursor Hover Effect
- 30Tailwind Magnetic Cursor Pull Hover Effect
Tailwind Card Flip Hover Effect
Four flips — horizontal, vertical, a diagonal rotate3d peel and a fanning stack. backface-hidden and transform-3d are core utilities, so the three-element scene/card/face structure ports without a single custom rule.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="thv-14 w-full min-h-svh grid place-items-center bg-thv14-bg font-thv14-sans px-6 py-14">
<div class="w-[min(760px,100%)] grid grid-cols-[repeat(auto-fit,minmax(260px,1fr))] gap-10">
<button type="button" class="group perspective-[800px] block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-rose">
<span class="relative block w-full h-full transform-3d transition-transform duration-650 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-y-180 group-focus-visible:rotate-y-180 motion-reduce:transition-none">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden bg-thv14-rose/20 border border-thv14-rose/40 text-thv14-text">
<span class="text-3xl">♦</span><span class="text-base font-bold">Hover Me</span><span class="text-xs tracking-[0.05em] text-thv14-dim">horizontal flip →</span>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden rotate-y-180 bg-thv14-rose text-white">
<span class="text-3xl">✦</span><span class="text-base font-bold">Revealed!</span><span class="text-xs tracking-[0.05em] text-white/80">back face content</span>
</span>
</span>
</button>
<button type="button" class="group perspective-[800px] block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-teal">
<span class="relative block w-full h-full transform-3d transition-transform duration-650 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-x-180 group-focus-visible:rotate-x-180 motion-reduce:transition-none">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden bg-thv14-teal/20 border border-thv14-teal/40 text-thv14-text">
<span class="text-3xl">◈</span><span class="text-base font-bold">Vertical</span><span class="text-xs tracking-[0.05em] text-thv14-dim">↓ flip over top</span>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden rotate-x-180 bg-thv14-indigo text-white">
<span class="text-3xl">❋</span><span class="text-base font-bold">Back Face</span><span class="text-xs tracking-[0.05em] text-white/80">rotateX flip</span>
</span>
</span>
</button>
<button type="button" class="group perspective-[800px] block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-amber">
<span class="relative block w-full h-full transform-3d transition-transform duration-650 ease-[cubic-bezier(.4,0,.2,1)] group-hover:[transform:rotate3d(1,1,0,180deg)] group-focus-visible:[transform:rotate3d(1,1,0,180deg)] motion-reduce:transition-none">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden bg-thv14-amber/20 border border-thv14-amber/40 text-thv14-text">
<span class="text-3xl">◬</span><span class="text-base font-bold">Diagonal</span><span class="text-xs tracking-[0.05em] text-thv14-dim">corner-peel axis</span>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden [transform:rotate3d(1,1,0,180deg)] bg-thv14-orange text-white">
<span class="text-3xl">⟡</span><span class="text-base font-bold">Peeled!</span><span class="text-xs tracking-[0.05em] text-white/80">rotate3d(1,1,0)</span>
</span>
</span>
</button>
<button type="button" class="group perspective-[900px] relative block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-violet">
<span class="absolute inset-0 z-30 flex items-center justify-center rounded-2xl border border-white/10 bg-thv14-violet/25 origin-bottom transition-transform duration-400 ease-[cubic-bezier(.4,0,.2,1)]"><span class="text-lg font-bold text-thv14-lilac">Fan</span></span>
<span class="absolute inset-0 z-20 rounded-2xl border border-white/10 bg-thv14-violet/20 origin-bottom transition-transform duration-400 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-y-[-30deg] group-focus-visible:rotate-y-[-30deg] motion-reduce:transition-none"></span>
<span class="absolute inset-0 z-10 rounded-2xl border border-white/10 bg-thv14-violet/15 origin-bottom transition-transform duration-400 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-y-[-55deg] group-focus-visible:rotate-y-[-55deg] motion-reduce:transition-none"></span>
<span class="absolute -bottom-7 inset-x-0 text-[11px] tracking-[0.12em] uppercase text-thv14-dim">hover the stack</span>
</button>
</div>
</section><section class="thv-14 w-full min-h-svh grid place-items-center bg-thv14-bg font-thv14-sans px-6 py-14">
<div class="w-[min(760px,100%)] grid grid-cols-[repeat(auto-fit,minmax(260px,1fr))] gap-10">
<button type="button" class="group perspective-[800px] block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-rose">
<span class="relative block w-full h-full transform-3d transition-transform duration-650 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-y-180 group-focus-visible:rotate-y-180 motion-reduce:transition-none">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden bg-thv14-rose/20 border border-thv14-rose/40 text-thv14-text">
<span class="text-3xl">♦</span><span class="text-base font-bold">Hover Me</span><span class="text-xs tracking-[0.05em] text-thv14-dim">horizontal flip →</span>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden rotate-y-180 bg-thv14-rose text-white">
<span class="text-3xl">✦</span><span class="text-base font-bold">Revealed!</span><span class="text-xs tracking-[0.05em] text-white/80">back face content</span>
</span>
</span>
</button>
<button type="button" class="group perspective-[800px] block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-teal">
<span class="relative block w-full h-full transform-3d transition-transform duration-650 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-x-180 group-focus-visible:rotate-x-180 motion-reduce:transition-none">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden bg-thv14-teal/20 border border-thv14-teal/40 text-thv14-text">
<span class="text-3xl">◈</span><span class="text-base font-bold">Vertical</span><span class="text-xs tracking-[0.05em] text-thv14-dim">↓ flip over top</span>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden rotate-x-180 bg-thv14-indigo text-white">
<span class="text-3xl">❋</span><span class="text-base font-bold">Back Face</span><span class="text-xs tracking-[0.05em] text-white/80">rotateX flip</span>
</span>
</span>
</button>
<button type="button" class="group perspective-[800px] block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-amber">
<span class="relative block w-full h-full transform-3d transition-transform duration-650 ease-[cubic-bezier(.4,0,.2,1)] group-hover:[transform:rotate3d(1,1,0,180deg)] group-focus-visible:[transform:rotate3d(1,1,0,180deg)] motion-reduce:transition-none">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden bg-thv14-amber/20 border border-thv14-amber/40 text-thv14-text">
<span class="text-3xl">◬</span><span class="text-base font-bold">Diagonal</span><span class="text-xs tracking-[0.05em] text-thv14-dim">corner-peel axis</span>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden [transform:rotate3d(1,1,0,180deg)] bg-thv14-orange text-white">
<span class="text-3xl">⟡</span><span class="text-base font-bold">Peeled!</span><span class="text-xs tracking-[0.05em] text-white/80">rotate3d(1,1,0)</span>
</span>
</span>
</button>
<button type="button" class="group perspective-[900px] relative block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-violet">
<span class="absolute inset-0 z-30 flex items-center justify-center rounded-2xl border border-white/10 bg-thv14-violet/25 origin-bottom transition-transform duration-400 ease-[cubic-bezier(.4,0,.2,1)]"><span class="text-lg font-bold text-thv14-lilac">Fan</span></span>
<span class="absolute inset-0 z-20 rounded-2xl border border-white/10 bg-thv14-violet/20 origin-bottom transition-transform duration-400 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-y-[-30deg] group-focus-visible:rotate-y-[-30deg] motion-reduce:transition-none"></span>
<span class="absolute inset-0 z-10 rounded-2xl border border-white/10 bg-thv14-violet/15 origin-bottom transition-transform duration-400 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-y-[-55deg] group-focus-visible:rotate-y-[-55deg] motion-reduce:transition-none"></span>
<span class="absolute -bottom-7 inset-x-0 text-[11px] tracking-[0.12em] uppercase text-thv14-dim">hover the stack</span>
</button>
</div>
</section>@import "tailwindcss";
@theme {
--color-thv14-bg: #0a0008;
--color-thv14-bg: oklch(0.11 0.02 350);
--color-thv14-text: #ffe4e6;
--color-thv14-text: oklch(0.94 0.03 10);
--color-thv14-dim: #7d7480;
--color-thv14-dim: oklch(0.6 0.02 350);
--color-thv14-rose: #be123c;
--color-thv14-rose: oklch(0.52 0.2 15);
--color-thv14-teal: #0d9488;
--color-thv14-teal: oklch(0.6 0.12 180);
--color-thv14-indigo: #4338ca;
--color-thv14-indigo: oklch(0.45 0.22 274);
--color-thv14-amber: #b45309;
--color-thv14-amber: oklch(0.55 0.14 55);
--color-thv14-orange: #c2410c;
--color-thv14-orange: oklch(0.55 0.18 40);
--color-thv14-violet: #8b5cf6;
--color-thv14-violet: oklch(0.63 0.21 295);
--color-thv14-lilac: #c4b5fd;
--color-thv14-lilac: oklch(0.83 0.09 295);
--font-thv14-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-14 {
width: 100%;
min-height: 100svh;
}
.thv-14 ::selection {
background: var(--color-thv14-rose);
color: #fff;
}@import "tailwindcss";
@theme {
--color-thv14-bg: #0a0008;
--color-thv14-bg: oklch(0.11 0.02 350);
--color-thv14-text: #ffe4e6;
--color-thv14-text: oklch(0.94 0.03 10);
--color-thv14-dim: #7d7480;
--color-thv14-dim: oklch(0.6 0.02 350);
--color-thv14-rose: #be123c;
--color-thv14-rose: oklch(0.52 0.2 15);
--color-thv14-teal: #0d9488;
--color-thv14-teal: oklch(0.6 0.12 180);
--color-thv14-indigo: #4338ca;
--color-thv14-indigo: oklch(0.45 0.22 274);
--color-thv14-amber: #b45309;
--color-thv14-amber: oklch(0.55 0.14 55);
--color-thv14-orange: #c2410c;
--color-thv14-orange: oklch(0.55 0.18 40);
--color-thv14-violet: #8b5cf6;
--color-thv14-violet: oklch(0.63 0.21 295);
--color-thv14-lilac: #c4b5fd;
--color-thv14-lilac: oklch(0.83 0.09 295);
--font-thv14-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-14 {
width: 100%;
min-height: 100svh;
}
.thv-14 ::selection {
background: var(--color-thv14-rose);
color: #fff;
}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-thv14-bg: #0a0008;
--color-thv14-bg: oklch(0.11 0.02 350);
--color-thv14-text: #ffe4e6;
--color-thv14-text: oklch(0.94 0.03 10);
--color-thv14-dim: #7d7480;
--color-thv14-dim: oklch(0.6 0.02 350);
--color-thv14-rose: #be123c;
--color-thv14-rose: oklch(0.52 0.2 15);
--color-thv14-teal: #0d9488;
--color-thv14-teal: oklch(0.6 0.12 180);
--color-thv14-indigo: #4338ca;
--color-thv14-indigo: oklch(0.45 0.22 274);
--color-thv14-amber: #b45309;
--color-thv14-amber: oklch(0.55 0.14 55);
--color-thv14-orange: #c2410c;
--color-thv14-orange: oklch(0.55 0.18 40);
--color-thv14-violet: #8b5cf6;
--color-thv14-violet: oklch(0.63 0.21 295);
--color-thv14-lilac: #c4b5fd;
--color-thv14-lilac: oklch(0.83 0.09 295);
--font-thv14-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-14 {
width: 100%;
min-height: 100svh;
}
.thv-14 ::selection {
background: var(--color-thv14-rose);
color: #fff;
}@import "tailwindcss";
@theme {
--color-thv14-bg: #0a0008;
--color-thv14-bg: oklch(0.11 0.02 350);
--color-thv14-text: #ffe4e6;
--color-thv14-text: oklch(0.94 0.03 10);
--color-thv14-dim: #7d7480;
--color-thv14-dim: oklch(0.6 0.02 350);
--color-thv14-rose: #be123c;
--color-thv14-rose: oklch(0.52 0.2 15);
--color-thv14-teal: #0d9488;
--color-thv14-teal: oklch(0.6 0.12 180);
--color-thv14-indigo: #4338ca;
--color-thv14-indigo: oklch(0.45 0.22 274);
--color-thv14-amber: #b45309;
--color-thv14-amber: oklch(0.55 0.14 55);
--color-thv14-orange: #c2410c;
--color-thv14-orange: oklch(0.55 0.18 40);
--color-thv14-violet: #8b5cf6;
--color-thv14-violet: oklch(0.63 0.21 295);
--color-thv14-lilac: #c4b5fd;
--color-thv14-lilac: oklch(0.83 0.09 295);
--font-thv14-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-14 {
width: 100%;
min-height: 100svh;
}
.thv-14 ::selection {
background: var(--color-thv14-rose);
color: #fff;
}<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=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;800&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=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Scene, card and face each hold exactly the utilities that define their role, which makes the classic "perspective on the wrong element" bug a reading error rather than a debugging session.
- UI change from the CSS original: each card is a
<button>that flips on focus. A hover-only flip hides its back-face content from every keyboard and touch user — the most substantive accessibility fix in the collection. - The fan variant keeps its top card static and rotates only the two behind it, so the label never leaves the focus ring.
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 Card Flip Hover Effect
Source: https://codefronts.com/motion/tailwind-css-hover-effects/tailwind-card-flip-hover-effect/
Four flips — horizontal, vertical, a diagonal rotate3d peel and a fanning stack. backface-hidden and transform-3d are core utilities, so the three-element scene/card/face structure ports without a single custom rule.
## HTML
```html
<section class="thv-14 w-full min-h-svh grid place-items-center bg-thv14-bg font-thv14-sans px-6 py-14">
<div class="w-[min(760px,100%)] grid grid-cols-[repeat(auto-fit,minmax(260px,1fr))] gap-10">
<button type="button" class="group perspective-[800px] block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-rose">
<span class="relative block w-full h-full transform-3d transition-transform duration-650 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-y-180 group-focus-visible:rotate-y-180 motion-reduce:transition-none">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden bg-thv14-rose/20 border border-thv14-rose/40 text-thv14-text">
<span class="text-3xl">♦</span><span class="text-base font-bold">Hover Me</span><span class="text-xs tracking-[0.05em] text-thv14-dim">horizontal flip →</span>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden rotate-y-180 bg-thv14-rose text-white">
<span class="text-3xl">✦</span><span class="text-base font-bold">Revealed!</span><span class="text-xs tracking-[0.05em] text-white/80">back face content</span>
</span>
</span>
</button>
<button type="button" class="group perspective-[800px] block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-teal">
<span class="relative block w-full h-full transform-3d transition-transform duration-650 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-x-180 group-focus-visible:rotate-x-180 motion-reduce:transition-none">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden bg-thv14-teal/20 border border-thv14-teal/40 text-thv14-text">
<span class="text-3xl">◈</span><span class="text-base font-bold">Vertical</span><span class="text-xs tracking-[0.05em] text-thv14-dim">↓ flip over top</span>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden rotate-x-180 bg-thv14-indigo text-white">
<span class="text-3xl">❋</span><span class="text-base font-bold">Back Face</span><span class="text-xs tracking-[0.05em] text-white/80">rotateX flip</span>
</span>
</span>
</button>
<button type="button" class="group perspective-[800px] block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-amber">
<span class="relative block w-full h-full transform-3d transition-transform duration-650 ease-[cubic-bezier(.4,0,.2,1)] group-hover:[transform:rotate3d(1,1,0,180deg)] group-focus-visible:[transform:rotate3d(1,1,0,180deg)] motion-reduce:transition-none">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden bg-thv14-amber/20 border border-thv14-amber/40 text-thv14-text">
<span class="text-3xl">◬</span><span class="text-base font-bold">Diagonal</span><span class="text-xs tracking-[0.05em] text-thv14-dim">corner-peel axis</span>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden [transform:rotate3d(1,1,0,180deg)] bg-thv14-orange text-white">
<span class="text-3xl">⟡</span><span class="text-base font-bold">Peeled!</span><span class="text-xs tracking-[0.05em] text-white/80">rotate3d(1,1,0)</span>
</span>
</span>
</button>
<button type="button" class="group perspective-[900px] relative block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-violet">
<span class="absolute inset-0 z-30 flex items-center justify-center rounded-2xl border border-white/10 bg-thv14-violet/25 origin-bottom transition-transform duration-400 ease-[cubic-bezier(.4,0,.2,1)]"><span class="text-lg font-bold text-thv14-lilac">Fan</span></span>
<span class="absolute inset-0 z-20 rounded-2xl border border-white/10 bg-thv14-violet/20 origin-bottom transition-transform duration-400 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-y-[-30deg] group-focus-visible:rotate-y-[-30deg] motion-reduce:transition-none"></span>
<span class="absolute inset-0 z-10 rounded-2xl border border-white/10 bg-thv14-violet/15 origin-bottom transition-transform duration-400 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-y-[-55deg] group-focus-visible:rotate-y-[-55deg] motion-reduce:transition-none"></span>
<span class="absolute -bottom-7 inset-x-0 text-[11px] tracking-[0.12em] uppercase text-thv14-dim">hover the stack</span>
</button>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-thv14-bg: #0a0008;
--color-thv14-bg: oklch(0.11 0.02 350);
--color-thv14-text: #ffe4e6;
--color-thv14-text: oklch(0.94 0.03 10);
--color-thv14-dim: #7d7480;
--color-thv14-dim: oklch(0.6 0.02 350);
--color-thv14-rose: #be123c;
--color-thv14-rose: oklch(0.52 0.2 15);
--color-thv14-teal: #0d9488;
--color-thv14-teal: oklch(0.6 0.12 180);
--color-thv14-indigo: #4338ca;
--color-thv14-indigo: oklch(0.45 0.22 274);
--color-thv14-amber: #b45309;
--color-thv14-amber: oklch(0.55 0.14 55);
--color-thv14-orange: #c2410c;
--color-thv14-orange: oklch(0.55 0.18 40);
--color-thv14-violet: #8b5cf6;
--color-thv14-violet: oklch(0.63 0.21 295);
--color-thv14-lilac: #c4b5fd;
--color-thv14-lilac: oklch(0.83 0.09 295);
--font-thv14-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-14 {
width: 100%;
min-height: 100svh;
}
.thv-14 ::selection {
background: var(--color-thv14-rose);
color: #fff;
}
```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 Card Flip Hover Effect
Source: https://codefronts.com/motion/tailwind-css-hover-effects/tailwind-card-flip-hover-effect/
Four flips — horizontal, vertical, a diagonal rotate3d peel and a fanning stack. backface-hidden and transform-3d are core utilities, so the three-element scene/card/face structure ports without a single custom rule.
## HTML
```html
<section class="thv-14 w-full min-h-svh grid place-items-center bg-thv14-bg font-thv14-sans px-6 py-14">
<div class="w-[min(760px,100%)] grid grid-cols-[repeat(auto-fit,minmax(260px,1fr))] gap-10">
<button type="button" class="group perspective-[800px] block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-rose">
<span class="relative block w-full h-full transform-3d transition-transform duration-650 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-y-180 group-focus-visible:rotate-y-180 motion-reduce:transition-none">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden bg-thv14-rose/20 border border-thv14-rose/40 text-thv14-text">
<span class="text-3xl">♦</span><span class="text-base font-bold">Hover Me</span><span class="text-xs tracking-[0.05em] text-thv14-dim">horizontal flip →</span>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden rotate-y-180 bg-thv14-rose text-white">
<span class="text-3xl">✦</span><span class="text-base font-bold">Revealed!</span><span class="text-xs tracking-[0.05em] text-white/80">back face content</span>
</span>
</span>
</button>
<button type="button" class="group perspective-[800px] block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-teal">
<span class="relative block w-full h-full transform-3d transition-transform duration-650 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-x-180 group-focus-visible:rotate-x-180 motion-reduce:transition-none">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden bg-thv14-teal/20 border border-thv14-teal/40 text-thv14-text">
<span class="text-3xl">◈</span><span class="text-base font-bold">Vertical</span><span class="text-xs tracking-[0.05em] text-thv14-dim">↓ flip over top</span>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden rotate-x-180 bg-thv14-indigo text-white">
<span class="text-3xl">❋</span><span class="text-base font-bold">Back Face</span><span class="text-xs tracking-[0.05em] text-white/80">rotateX flip</span>
</span>
</span>
</button>
<button type="button" class="group perspective-[800px] block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-amber">
<span class="relative block w-full h-full transform-3d transition-transform duration-650 ease-[cubic-bezier(.4,0,.2,1)] group-hover:[transform:rotate3d(1,1,0,180deg)] group-focus-visible:[transform:rotate3d(1,1,0,180deg)] motion-reduce:transition-none">
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden bg-thv14-amber/20 border border-thv14-amber/40 text-thv14-text">
<span class="text-3xl">◬</span><span class="text-base font-bold">Diagonal</span><span class="text-xs tracking-[0.05em] text-thv14-dim">corner-peel axis</span>
</span>
<span class="absolute inset-0 flex flex-col items-center justify-center gap-2.5 p-6 rounded-2xl backface-hidden [transform:rotate3d(1,1,0,180deg)] bg-thv14-orange text-white">
<span class="text-3xl">⟡</span><span class="text-base font-bold">Peeled!</span><span class="text-xs tracking-[0.05em] text-white/80">rotate3d(1,1,0)</span>
</span>
</span>
</button>
<button type="button" class="group perspective-[900px] relative block w-full h-[220px] bg-transparent border-0 p-0 cursor-pointer rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv14-violet">
<span class="absolute inset-0 z-30 flex items-center justify-center rounded-2xl border border-white/10 bg-thv14-violet/25 origin-bottom transition-transform duration-400 ease-[cubic-bezier(.4,0,.2,1)]"><span class="text-lg font-bold text-thv14-lilac">Fan</span></span>
<span class="absolute inset-0 z-20 rounded-2xl border border-white/10 bg-thv14-violet/20 origin-bottom transition-transform duration-400 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-y-[-30deg] group-focus-visible:rotate-y-[-30deg] motion-reduce:transition-none"></span>
<span class="absolute inset-0 z-10 rounded-2xl border border-white/10 bg-thv14-violet/15 origin-bottom transition-transform duration-400 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-y-[-55deg] group-focus-visible:rotate-y-[-55deg] motion-reduce:transition-none"></span>
<span class="absolute -bottom-7 inset-x-0 text-[11px] tracking-[0.12em] uppercase text-thv14-dim">hover the stack</span>
</button>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-thv14-bg: #0a0008;
--color-thv14-bg: oklch(0.11 0.02 350);
--color-thv14-text: #ffe4e6;
--color-thv14-text: oklch(0.94 0.03 10);
--color-thv14-dim: #7d7480;
--color-thv14-dim: oklch(0.6 0.02 350);
--color-thv14-rose: #be123c;
--color-thv14-rose: oklch(0.52 0.2 15);
--color-thv14-teal: #0d9488;
--color-thv14-teal: oklch(0.6 0.12 180);
--color-thv14-indigo: #4338ca;
--color-thv14-indigo: oklch(0.45 0.22 274);
--color-thv14-amber: #b45309;
--color-thv14-amber: oklch(0.55 0.14 55);
--color-thv14-orange: #c2410c;
--color-thv14-orange: oklch(0.55 0.18 40);
--color-thv14-violet: #8b5cf6;
--color-thv14-violet: oklch(0.63 0.21 295);
--color-thv14-lilac: #c4b5fd;
--color-thv14-lilac: oklch(0.83 0.09 295);
--font-thv14-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-14 {
width: 100%;
min-height: 100svh;
}
.thv-14 ::selection {
background: var(--color-thv14-rose);
color: #fff;
}
```How this works
The back face rests flipped. Both faces are absolute inset-0 backface-hidden; the back carries rotate-y-180 at rest, so rotating the card 180° brings it forward while hiding the front.
The trigger sits on the scene. group goes on the outer button and the card reads group-hover:rotate-y-180 group-focus-visible:rotate-y-180, which keeps the flip working when the pointer crosses the card's own edges mid-rotation.
The fan uses siblings, not faces. Three stacked panels with origin-bottom and increasing group-hover:rotate-y-* values unfurl in place.
Make it yours
- Flip speed:
duration-300snappy,duration-1000ceremonial. - Flip axis: swap
rotate-y-180forrotate-x-180and flip the back face to match. - Put real content on the back — pricing, a CTA — and the flip stops being decorative.
Gotchas — read before shipping
backface-hiddenmust be on both faces; omit either and it ghosts through mid-turn.overflow-hiddenon the card collapses the 3D context — put radii on the faces instead.- A flip card must be keyboard-operable, since its back face carries content. That is what the
group-focus-visible:twins are for.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
backface-visibility and preserve-3d are Baseline; Tailwind emits the -webkit- pair.