23 / 36
All 36 in 36 Tailwind CSS Button Hover Effects
- 01Tailwind Magnetic Ripple Attraction Button Hover Effect
- 02Tailwind Cyberpunk Holographic Glitch Grid Button
- 03Tailwind Frosted Glassmorphism Shimmer Glow Button
- 04Tailwind Organic Blob Morph Button Hover Effect
- 05Tailwind Dual-Line Intersection Border Draw Button
- 06Tailwind Isometric Tactile 3D Depress Button
- 07Tailwind Infinite Sliding Kinetic Marquee Button
- 08Tailwind Chroma Conic Gradient Border Spin Button
- 09Tailwind Minimalist Border & Outline Drawing Hover Effects
- 10Tailwind Modern 3D Skeuomorphic Button Press Effects
- 11Tailwind Neo-Brutalist & Cyberpunk Button Glow Effects
- 12Tailwind Sliding Background Color Wipe Button Effects
- 13Tailwind Liquid Fill & Organic Morphing Button Effects
- 14Tailwind Kinetic Text Flip & Icon Reveal Button Effects
- 15Tailwind Liquid Wave Fill Button Hover Effect
- 16Tailwind Magnetic Border Drift Button
- 17Tailwind Glitch Slice Button Hover Effect
- 18Tailwind Neon Pulse Glow Button Hover Effect
- 19Tailwind Split Reveal Curtain Button Effect
- 20Tailwind Diagonal Shutter Sweep Button Effect
- 21Tailwind Elastic Lift Spring Button Hover Effect
- 22Tailwind Center Underline Draw Link Button Effects
- 23Tailwind 3D Flip Card Button Hover Effect
- 24Tailwind Particle Burst Confetti Button Effect
- 25Tailwind Slide Doors Closing Panel Button Effect
- 26Tailwind Typewriter Retype Terminal Button Effect
- 27Tailwind Hard Shadow Shift Flat Button Effect
- 28Tailwind Material Ripple Wave Button Effect
- 29Tailwind Rainbow Gradient Border Spin Button
- 30Tailwind Morph Shape Silhouette Button Effects
- 31Tailwind Icon Slide In Directional Button Effect
- 32Tailwind Cursor Spotlight Glow Button
- 33Tailwind Stagger Fill Equaliser Button Effect
- 34Tailwind Sunburst Expand Radiant Button Effect
- 35Tailwind 3D Press Plunger Key Button Effect
- 36Tailwind Add-to-Cart Liquid Glass Ripple Button
Tailwind 3D Flip Card Button Hover Effect
A CTA that flips like a physical card: on hover it rotates 180° in 3D to reveal a styled back face with a different label and colour. Three properties have to be exactly right — perspective, transform-style and backface-visibility — and the port puts all three where you can see them.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<div class="tbh-23-group w-full min-h-svh flex flex-wrap">
<section class="tbh-23a flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh23-sans bg-tbh23a-stage [perspective:900px]" aria-label="3D flip button">
<button type="button" aria-label="Follow" class="group/btn w-[200px] h-[58px] p-0 cursor-pointer border-0 rounded-xl bg-transparent text-base font-extrabold text-white focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-4">
<span class="relative block w-full h-full transform-3d transition-[rotate] duration-500 ease-[cubic-bezier(.4,0,.2,1)] group-hover/btn:[rotate:y_180deg] group-focus-visible/btn:[rotate:y_180deg] motion-reduce:transition-none">
<span class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23a-facea [backface-visibility:hidden]">Follow</span>
<span aria-hidden="true" class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23a-faceb [backface-visibility:hidden] [rotate:y_180deg]">Following ✓</span>
</span>
</button>
</section>
<section class="tbh-23b flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh23-sans bg-tbh23b-stage [perspective:700px]" aria-label="3D roll button">
<button type="button" aria-label="Download" class="group/btn w-[190px] h-[58px] p-0 cursor-pointer border-0 rounded-xl bg-transparent text-base font-extrabold text-white focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-4">
<span class="relative block w-full h-full transform-3d transition-[rotate] duration-500 ease-[cubic-bezier(.4,0,.2,1)] group-hover/btn:[rotate:x_180deg] group-focus-visible/btn:[rotate:x_180deg] motion-reduce:transition-none">
<span class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23b-facea [backface-visibility:hidden]">Download</span>
<span aria-hidden="true" class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23b-faceb [backface-visibility:hidden] [rotate:x_180deg]">Saved ↓</span>
</span>
</button>
</section>
</div><div class="tbh-23-group w-full min-h-svh flex flex-wrap">
<section class="tbh-23a flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh23-sans bg-tbh23a-stage [perspective:900px]" aria-label="3D flip button">
<button type="button" aria-label="Follow" class="group/btn w-[200px] h-[58px] p-0 cursor-pointer border-0 rounded-xl bg-transparent text-base font-extrabold text-white focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-4">
<span class="relative block w-full h-full transform-3d transition-[rotate] duration-500 ease-[cubic-bezier(.4,0,.2,1)] group-hover/btn:[rotate:y_180deg] group-focus-visible/btn:[rotate:y_180deg] motion-reduce:transition-none">
<span class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23a-facea [backface-visibility:hidden]">Follow</span>
<span aria-hidden="true" class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23a-faceb [backface-visibility:hidden] [rotate:y_180deg]">Following ✓</span>
</span>
</button>
</section>
<section class="tbh-23b flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh23-sans bg-tbh23b-stage [perspective:700px]" aria-label="3D roll button">
<button type="button" aria-label="Download" class="group/btn w-[190px] h-[58px] p-0 cursor-pointer border-0 rounded-xl bg-transparent text-base font-extrabold text-white focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-4">
<span class="relative block w-full h-full transform-3d transition-[rotate] duration-500 ease-[cubic-bezier(.4,0,.2,1)] group-hover/btn:[rotate:x_180deg] group-focus-visible/btn:[rotate:x_180deg] motion-reduce:transition-none">
<span class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23b-facea [backface-visibility:hidden]">Download</span>
<span aria-hidden="true" class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23b-faceb [backface-visibility:hidden] [rotate:x_180deg]">Saved ↓</span>
</span>
</button>
</section>
</div>@import "tailwindcss";
@theme {
--color-tbh23a-facea: #5470c4;
--color-tbh23a-facea: oklch(0.55 0.16 265);
--color-tbh23a-faceb: #4aa878;
--color-tbh23a-faceb: oklch(0.6 0.15 155);
--color-tbh23a-stage: #101018;
--color-tbh23a-stage: oklch(0.15 0.01 285);
--color-tbh23b-facea: #3e93b8;
--color-tbh23b-facea: oklch(0.56 0.16 210);
--color-tbh23b-faceb: #52b07f;
--color-tbh23b-faceb: oklch(0.62 0.15 145);
--color-tbh23b-stage: #0a1418;
--color-tbh23b-stage: oklch(0.14 0.02 210);
--font-tbh23-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Stays CSS: Safari's prefixed backface-visibility, which has no utility form. */
.tbh-23a span span,
.tbh-23b span span {
-webkit-backface-visibility: hidden;
}
.tbh-23-group {
width: 100%;
min-height: 100svh;
}
.tbh-23a,
.tbh-23b {
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tbh23a-facea: #5470c4;
--color-tbh23a-facea: oklch(0.55 0.16 265);
--color-tbh23a-faceb: #4aa878;
--color-tbh23a-faceb: oklch(0.6 0.15 155);
--color-tbh23a-stage: #101018;
--color-tbh23a-stage: oklch(0.15 0.01 285);
--color-tbh23b-facea: #3e93b8;
--color-tbh23b-facea: oklch(0.56 0.16 210);
--color-tbh23b-faceb: #52b07f;
--color-tbh23b-faceb: oklch(0.62 0.15 145);
--color-tbh23b-stage: #0a1418;
--color-tbh23b-stage: oklch(0.14 0.02 210);
--font-tbh23-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Stays CSS: Safari's prefixed backface-visibility, which has no utility form. */
.tbh-23a span span,
.tbh-23b span span {
-webkit-backface-visibility: hidden;
}
.tbh-23-group {
width: 100%;
min-height: 100svh;
}
.tbh-23a,
.tbh-23b {
min-height: 100svh;
}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-tbh23a-facea: #5470c4;
--color-tbh23a-facea: oklch(0.55 0.16 265);
--color-tbh23a-faceb: #4aa878;
--color-tbh23a-faceb: oklch(0.6 0.15 155);
--color-tbh23a-stage: #101018;
--color-tbh23a-stage: oklch(0.15 0.01 285);
--color-tbh23b-facea: #3e93b8;
--color-tbh23b-facea: oklch(0.56 0.16 210);
--color-tbh23b-faceb: #52b07f;
--color-tbh23b-faceb: oklch(0.62 0.15 145);
--color-tbh23b-stage: #0a1418;
--color-tbh23b-stage: oklch(0.14 0.02 210);
--font-tbh23-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Stays CSS: Safari's prefixed backface-visibility, which has no utility form. */
.tbh-23a span span,
.tbh-23b span span {
-webkit-backface-visibility: hidden;
}
.tbh-23-group {
width: 100%;
min-height: 100svh;
}
.tbh-23a,
.tbh-23b {
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tbh23a-facea: #5470c4;
--color-tbh23a-facea: oklch(0.55 0.16 265);
--color-tbh23a-faceb: #4aa878;
--color-tbh23a-faceb: oklch(0.6 0.15 155);
--color-tbh23a-stage: #101018;
--color-tbh23a-stage: oklch(0.15 0.01 285);
--color-tbh23b-facea: #3e93b8;
--color-tbh23b-facea: oklch(0.56 0.16 210);
--color-tbh23b-faceb: #52b07f;
--color-tbh23b-faceb: oklch(0.62 0.15 145);
--color-tbh23b-stage: #0a1418;
--color-tbh23b-stage: oklch(0.14 0.02 210);
--font-tbh23-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Stays CSS: Safari's prefixed backface-visibility, which has no utility form. */
.tbh-23a span span,
.tbh-23b span span {
-webkit-backface-visibility: hidden;
}
.tbh-23-group {
width: 100%;
min-height: 100svh;
}
.tbh-23a,
.tbh-23b {
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=Space+Grotesk:wght@400;500;600;700&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&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
transform-3dis a real v4 utility (it compiles totransform-style: preserve-3d), while perspective, backface-visibility and the axis rotations are arbitrary properties — which is the correct split: one is a mode, the others are scene values.- Writing the rotations as
[rotate:y_180deg]keeps them on the discreterotateproperty, so the pre-rotated back face and the inner's hover rotation compose cleanly instead of one overwriting a sharedtransform. - UI change from the CSS original: both flips now fire on
group-focus-visible/btn:, and the focus ring was moved to the outer button (the original put it on an element that rotates, so at 180deg the ring was facing away from the viewer).
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 Flip Card Button Hover Effect
Source: https://codefronts.com/motion/tailwind-css-button-hover-effects/tailwind-3d-flip-card-button-hover-effect/
A CTA that flips like a physical card: on hover it rotates 180° in 3D to reveal a styled back face with a different label and colour. Three properties have to be exactly right — perspective, transform-style and backface-visibility — and the port puts all three where you can see them.
## HTML
```html
<div class="tbh-23-group w-full min-h-svh flex flex-wrap">
<section class="tbh-23a flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh23-sans bg-tbh23a-stage [perspective:900px]" aria-label="3D flip button">
<button type="button" aria-label="Follow" class="group/btn w-[200px] h-[58px] p-0 cursor-pointer border-0 rounded-xl bg-transparent text-base font-extrabold text-white focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-4">
<span class="relative block w-full h-full transform-3d transition-[rotate] duration-500 ease-[cubic-bezier(.4,0,.2,1)] group-hover/btn:[rotate:y_180deg] group-focus-visible/btn:[rotate:y_180deg] motion-reduce:transition-none">
<span class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23a-facea [backface-visibility:hidden]">Follow</span>
<span aria-hidden="true" class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23a-faceb [backface-visibility:hidden] [rotate:y_180deg]">Following ✓</span>
</span>
</button>
</section>
<section class="tbh-23b flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh23-sans bg-tbh23b-stage [perspective:700px]" aria-label="3D roll button">
<button type="button" aria-label="Download" class="group/btn w-[190px] h-[58px] p-0 cursor-pointer border-0 rounded-xl bg-transparent text-base font-extrabold text-white focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-4">
<span class="relative block w-full h-full transform-3d transition-[rotate] duration-500 ease-[cubic-bezier(.4,0,.2,1)] group-hover/btn:[rotate:x_180deg] group-focus-visible/btn:[rotate:x_180deg] motion-reduce:transition-none">
<span class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23b-facea [backface-visibility:hidden]">Download</span>
<span aria-hidden="true" class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23b-faceb [backface-visibility:hidden] [rotate:x_180deg]">Saved ↓</span>
</span>
</button>
</section>
</div>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tbh23a-facea: #5470c4;
--color-tbh23a-facea: oklch(0.55 0.16 265);
--color-tbh23a-faceb: #4aa878;
--color-tbh23a-faceb: oklch(0.6 0.15 155);
--color-tbh23a-stage: #101018;
--color-tbh23a-stage: oklch(0.15 0.01 285);
--color-tbh23b-facea: #3e93b8;
--color-tbh23b-facea: oklch(0.56 0.16 210);
--color-tbh23b-faceb: #52b07f;
--color-tbh23b-faceb: oklch(0.62 0.15 145);
--color-tbh23b-stage: #0a1418;
--color-tbh23b-stage: oklch(0.14 0.02 210);
--font-tbh23-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Stays CSS: Safari's prefixed backface-visibility, which has no utility form. */
.tbh-23a span span,
.tbh-23b span span {
-webkit-backface-visibility: hidden;
}
.tbh-23-group {
width: 100%;
min-height: 100svh;
}
.tbh-23a,
.tbh-23b {
min-height: 100svh;
}
```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 Flip Card Button Hover Effect
Source: https://codefronts.com/motion/tailwind-css-button-hover-effects/tailwind-3d-flip-card-button-hover-effect/
A CTA that flips like a physical card: on hover it rotates 180° in 3D to reveal a styled back face with a different label and colour. Three properties have to be exactly right — perspective, transform-style and backface-visibility — and the port puts all three where you can see them.
## HTML
```html
<div class="tbh-23-group w-full min-h-svh flex flex-wrap">
<section class="tbh-23a flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh23-sans bg-tbh23a-stage [perspective:900px]" aria-label="3D flip button">
<button type="button" aria-label="Follow" class="group/btn w-[200px] h-[58px] p-0 cursor-pointer border-0 rounded-xl bg-transparent text-base font-extrabold text-white focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-4">
<span class="relative block w-full h-full transform-3d transition-[rotate] duration-500 ease-[cubic-bezier(.4,0,.2,1)] group-hover/btn:[rotate:y_180deg] group-focus-visible/btn:[rotate:y_180deg] motion-reduce:transition-none">
<span class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23a-facea [backface-visibility:hidden]">Follow</span>
<span aria-hidden="true" class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23a-faceb [backface-visibility:hidden] [rotate:y_180deg]">Following ✓</span>
</span>
</button>
</section>
<section class="tbh-23b flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh23-sans bg-tbh23b-stage [perspective:700px]" aria-label="3D roll button">
<button type="button" aria-label="Download" class="group/btn w-[190px] h-[58px] p-0 cursor-pointer border-0 rounded-xl bg-transparent text-base font-extrabold text-white focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-4">
<span class="relative block w-full h-full transform-3d transition-[rotate] duration-500 ease-[cubic-bezier(.4,0,.2,1)] group-hover/btn:[rotate:x_180deg] group-focus-visible/btn:[rotate:x_180deg] motion-reduce:transition-none">
<span class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23b-facea [backface-visibility:hidden]">Download</span>
<span aria-hidden="true" class="absolute inset-0 grid place-items-center rounded-xl bg-tbh23b-faceb [backface-visibility:hidden] [rotate:x_180deg]">Saved ↓</span>
</span>
</button>
</section>
</div>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tbh23a-facea: #5470c4;
--color-tbh23a-facea: oklch(0.55 0.16 265);
--color-tbh23a-faceb: #4aa878;
--color-tbh23a-faceb: oklch(0.6 0.15 155);
--color-tbh23a-stage: #101018;
--color-tbh23a-stage: oklch(0.15 0.01 285);
--color-tbh23b-facea: #3e93b8;
--color-tbh23b-facea: oklch(0.56 0.16 210);
--color-tbh23b-faceb: #52b07f;
--color-tbh23b-faceb: oklch(0.62 0.15 145);
--color-tbh23b-stage: #0a1418;
--color-tbh23b-stage: oklch(0.14 0.02 210);
--font-tbh23-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Stays CSS: Safari's prefixed backface-visibility, which has no utility form. */
.tbh-23a span span,
.tbh-23b span span {
-webkit-backface-visibility: hidden;
}
.tbh-23-group {
width: 100%;
min-height: 100svh;
}
.tbh-23a,
.tbh-23b {
min-height: 100svh;
}
```How this works
Three properties, one illusion. Perspective lives on the parent (depth of the scene), transform-3d on the inner (children keep their own Z), backface-visibility:hidden on the faces (each disappears when turned away). Miss any one and the flip either goes flat or shows mirrored text mid-rotation.
The back face is pre-rotated. It sits at 180deg permanently, so when the inner rotates 180deg the back arrives facing forward while the front turns away. Nothing is timed or faded; it is one rotation of a rigid body.
Design B flips on X. [rotate:x_180deg] instead of Y, which reads as a mechanical roll (a departures board) rather than a card turn — the better fit for a status change like Download → Saved.
Make it yours
- Axis:
[rotate:y_180deg]for a card flip,[rotate:x_180deg]for a roll. - Depth: the stage's
[perspective:900px]; lower values exaggerate the 3D dramatically (700px on design B). - Face colours:
--color-tbh23a-facea/-faceb— the contrast between them is what makes the flip legible at speed. - Pace:
duration-500withease-[cubic-bezier(.4,0,.2,1)]; under 350ms the mid-flip edge becomes hard to read.
Gotchas — read before shipping
[backface-visibility:hidden]is required on BOTH faces, and Safari needs the-webkit-form, which has no utility — it stays a two-line CSS rule.- The button must have an explicit width and height. Absolutely positioned faces contribute nothing to layout, so without it the button collapses.
- The back face must be
aria-hiddenand the button must carryaria-label, or the accessible name becomes 'Follow Following'. transform-3don the inner creates a containing block and a new 3D rendering context — do not put the focus ring on the inner, or it rotates away with the face.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
3D transforms and backface-visibility are universal (Safari needs the prefixed form, included); with CSS unavailable both faces render stacked and the button still works.