10 / 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 Fill Wipe Button Hover Effect
Six directional fills — left wipe, diagonal slash, radial burst, curtain drop, centre split and an inset flood. One pattern, six origin-* and transform pairings, which is exactly the kind of variation utilities are good at.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="thv-10 w-full min-h-svh grid place-items-center bg-thv10-bg font-thv10-sans px-6 py-14">
<div class="w-[min(860px,100%)] grid grid-cols-[repeat(auto-fit,minmax(230px,1fr))] gap-9">
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-red bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-red cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-red before:origin-left before:scale-x-0 before:transition-transform before:duration-350 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-x-100 focus-visible:text-white focus-visible:before:scale-x-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-red motion-reduce:before:transition-none"><span class="relative z-10">Left Wipe</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scaleX from left</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-rose bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-rose cursor-pointer transition-colors duration-400 before:content-[''] before:absolute before:-inset-[20%] before:-z-10 before:bg-thv10-rose before:origin-left before:-skew-x-[25deg] before:scale-x-0 before:transition-transform before:duration-500 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-x-100 focus-visible:text-white focus-visible:before:scale-x-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-rose motion-reduce:before:transition-none"><span class="relative z-10">Diagonal Slash</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">skew + scaleX</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-orange bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-orange cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-orange before:rounded-full before:scale-0 before:transition-transform before:duration-450 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-[3] focus-visible:text-white focus-visible:before:scale-[3] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-orange motion-reduce:before:transition-none"><span class="relative z-10">Radial Burst</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scale from center</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-coral bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-coral cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-coral before:origin-top before:scale-y-0 before:transition-transform before:duration-350 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-y-100 focus-visible:text-white focus-visible:before:scale-y-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-coral motion-reduce:before:transition-none"><span class="relative z-10">Curtain Drop</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scaleY from top</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-crimson bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-crimson cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-crimson before:origin-center before:scale-x-0 before:transition-transform before:duration-350 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-x-100 focus-visible:text-white focus-visible:before:scale-x-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-crimson motion-reduce:before:transition-none"><span class="relative z-10">Center Split</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scaleX outward</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="min-h-11 px-8 py-3 rounded-md border-2 border-thv10-red bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-red cursor-pointer shadow-[inset_0_0_0_0_var(--color-thv10-red)] transition-[box-shadow,color] duration-400 ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:shadow-[inset_0_0_0_60px_var(--color-thv10-red)] focus-visible:text-white focus-visible:shadow-[inset_0_0_0_60px_var(--color-thv10-red)] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-red motion-reduce:transition-none">Inset Grow</button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">box-shadow inset fill</span>
</div>
</div>
</section><section class="thv-10 w-full min-h-svh grid place-items-center bg-thv10-bg font-thv10-sans px-6 py-14">
<div class="w-[min(860px,100%)] grid grid-cols-[repeat(auto-fit,minmax(230px,1fr))] gap-9">
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-red bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-red cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-red before:origin-left before:scale-x-0 before:transition-transform before:duration-350 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-x-100 focus-visible:text-white focus-visible:before:scale-x-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-red motion-reduce:before:transition-none"><span class="relative z-10">Left Wipe</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scaleX from left</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-rose bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-rose cursor-pointer transition-colors duration-400 before:content-[''] before:absolute before:-inset-[20%] before:-z-10 before:bg-thv10-rose before:origin-left before:-skew-x-[25deg] before:scale-x-0 before:transition-transform before:duration-500 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-x-100 focus-visible:text-white focus-visible:before:scale-x-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-rose motion-reduce:before:transition-none"><span class="relative z-10">Diagonal Slash</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">skew + scaleX</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-orange bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-orange cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-orange before:rounded-full before:scale-0 before:transition-transform before:duration-450 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-[3] focus-visible:text-white focus-visible:before:scale-[3] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-orange motion-reduce:before:transition-none"><span class="relative z-10">Radial Burst</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scale from center</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-coral bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-coral cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-coral before:origin-top before:scale-y-0 before:transition-transform before:duration-350 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-y-100 focus-visible:text-white focus-visible:before:scale-y-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-coral motion-reduce:before:transition-none"><span class="relative z-10">Curtain Drop</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scaleY from top</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-crimson bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-crimson cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-crimson before:origin-center before:scale-x-0 before:transition-transform before:duration-350 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-x-100 focus-visible:text-white focus-visible:before:scale-x-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-crimson motion-reduce:before:transition-none"><span class="relative z-10">Center Split</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scaleX outward</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="min-h-11 px-8 py-3 rounded-md border-2 border-thv10-red bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-red cursor-pointer shadow-[inset_0_0_0_0_var(--color-thv10-red)] transition-[box-shadow,color] duration-400 ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:shadow-[inset_0_0_0_60px_var(--color-thv10-red)] focus-visible:text-white focus-visible:shadow-[inset_0_0_0_60px_var(--color-thv10-red)] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-red motion-reduce:transition-none">Inset Grow</button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">box-shadow inset fill</span>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-thv10-bg: #0f0400;
--color-thv10-bg: oklch(0.13 0.03 40);
--color-thv10-dim: #6b7280;
--color-thv10-dim: oklch(0.55 0.02 265);
--color-thv10-red: #ef4444;
--color-thv10-red: oklch(0.64 0.21 25);
--color-thv10-rose: #f43f5e;
--color-thv10-rose: oklch(0.65 0.23 16);
--color-thv10-orange: #f97316;
--color-thv10-orange: oklch(0.7 0.19 45);
--color-thv10-coral: #fb923c;
--color-thv10-coral: oklch(0.76 0.15 55);
--color-thv10-crimson: #dc2626;
--color-thv10-crimson: oklch(0.58 0.22 27);
--font-thv10-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-10 {
width: 100%;
min-height: 100svh;
}
.thv-10 ::selection {
background: var(--color-thv10-crimson);
color: #fff;
}@import "tailwindcss";
@theme {
--color-thv10-bg: #0f0400;
--color-thv10-bg: oklch(0.13 0.03 40);
--color-thv10-dim: #6b7280;
--color-thv10-dim: oklch(0.55 0.02 265);
--color-thv10-red: #ef4444;
--color-thv10-red: oklch(0.64 0.21 25);
--color-thv10-rose: #f43f5e;
--color-thv10-rose: oklch(0.65 0.23 16);
--color-thv10-orange: #f97316;
--color-thv10-orange: oklch(0.7 0.19 45);
--color-thv10-coral: #fb923c;
--color-thv10-coral: oklch(0.76 0.15 55);
--color-thv10-crimson: #dc2626;
--color-thv10-crimson: oklch(0.58 0.22 27);
--font-thv10-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-10 {
width: 100%;
min-height: 100svh;
}
.thv-10 ::selection {
background: var(--color-thv10-crimson);
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-thv10-bg: #0f0400;
--color-thv10-bg: oklch(0.13 0.03 40);
--color-thv10-dim: #6b7280;
--color-thv10-dim: oklch(0.55 0.02 265);
--color-thv10-red: #ef4444;
--color-thv10-red: oklch(0.64 0.21 25);
--color-thv10-rose: #f43f5e;
--color-thv10-rose: oklch(0.65 0.23 16);
--color-thv10-orange: #f97316;
--color-thv10-orange: oklch(0.7 0.19 45);
--color-thv10-coral: #fb923c;
--color-thv10-coral: oklch(0.76 0.15 55);
--color-thv10-crimson: #dc2626;
--color-thv10-crimson: oklch(0.58 0.22 27);
--font-thv10-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-10 {
width: 100%;
min-height: 100svh;
}
.thv-10 ::selection {
background: var(--color-thv10-crimson);
color: #fff;
}@import "tailwindcss";
@theme {
--color-thv10-bg: #0f0400;
--color-thv10-bg: oklch(0.13 0.03 40);
--color-thv10-dim: #6b7280;
--color-thv10-dim: oklch(0.55 0.02 265);
--color-thv10-red: #ef4444;
--color-thv10-red: oklch(0.64 0.21 25);
--color-thv10-rose: #f43f5e;
--color-thv10-rose: oklch(0.65 0.23 16);
--color-thv10-orange: #f97316;
--color-thv10-orange: oklch(0.7 0.19 45);
--color-thv10-coral: #fb923c;
--color-thv10-coral: oklch(0.76 0.15 55);
--color-thv10-crimson: #dc2626;
--color-thv10-crimson: oklch(0.58 0.22 27);
--font-thv10-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-10 {
width: 100%;
min-height: 100svh;
}
.thv-10 ::selection {
background: var(--color-thv10-crimson);
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.
- The clearest demonstration in the collection that a utility port turns variants into parameters: the six buttons differ by two tokens each.
- UI change from the CSS original: real buttons, 44px targets, focus rings and
focus-visible:fills throughout. - Tailwind's composable transform utilities remove a real footgun — the CSS version had to repeat
skewX(-25deg)in the hover rule or lose the diagonal.
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 Fill Wipe Button Hover Effect
Source: https://codefronts.com/motion/tailwind-css-hover-effects/tailwind-fill-wipe-button-hover-effect/
Six directional fills — left wipe, diagonal slash, radial burst, curtain drop, centre split and an inset flood. One pattern, six origin-* and transform pairings, which is exactly the kind of variation utilities are good at.
## HTML
```html
<section class="thv-10 w-full min-h-svh grid place-items-center bg-thv10-bg font-thv10-sans px-6 py-14">
<div class="w-[min(860px,100%)] grid grid-cols-[repeat(auto-fit,minmax(230px,1fr))] gap-9">
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-red bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-red cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-red before:origin-left before:scale-x-0 before:transition-transform before:duration-350 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-x-100 focus-visible:text-white focus-visible:before:scale-x-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-red motion-reduce:before:transition-none"><span class="relative z-10">Left Wipe</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scaleX from left</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-rose bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-rose cursor-pointer transition-colors duration-400 before:content-[''] before:absolute before:-inset-[20%] before:-z-10 before:bg-thv10-rose before:origin-left before:-skew-x-[25deg] before:scale-x-0 before:transition-transform before:duration-500 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-x-100 focus-visible:text-white focus-visible:before:scale-x-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-rose motion-reduce:before:transition-none"><span class="relative z-10">Diagonal Slash</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">skew + scaleX</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-orange bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-orange cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-orange before:rounded-full before:scale-0 before:transition-transform before:duration-450 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-[3] focus-visible:text-white focus-visible:before:scale-[3] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-orange motion-reduce:before:transition-none"><span class="relative z-10">Radial Burst</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scale from center</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-coral bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-coral cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-coral before:origin-top before:scale-y-0 before:transition-transform before:duration-350 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-y-100 focus-visible:text-white focus-visible:before:scale-y-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-coral motion-reduce:before:transition-none"><span class="relative z-10">Curtain Drop</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scaleY from top</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-crimson bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-crimson cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-crimson before:origin-center before:scale-x-0 before:transition-transform before:duration-350 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-x-100 focus-visible:text-white focus-visible:before:scale-x-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-crimson motion-reduce:before:transition-none"><span class="relative z-10">Center Split</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scaleX outward</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="min-h-11 px-8 py-3 rounded-md border-2 border-thv10-red bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-red cursor-pointer shadow-[inset_0_0_0_0_var(--color-thv10-red)] transition-[box-shadow,color] duration-400 ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:shadow-[inset_0_0_0_60px_var(--color-thv10-red)] focus-visible:text-white focus-visible:shadow-[inset_0_0_0_60px_var(--color-thv10-red)] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-red motion-reduce:transition-none">Inset Grow</button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">box-shadow inset fill</span>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-thv10-bg: #0f0400;
--color-thv10-bg: oklch(0.13 0.03 40);
--color-thv10-dim: #6b7280;
--color-thv10-dim: oklch(0.55 0.02 265);
--color-thv10-red: #ef4444;
--color-thv10-red: oklch(0.64 0.21 25);
--color-thv10-rose: #f43f5e;
--color-thv10-rose: oklch(0.65 0.23 16);
--color-thv10-orange: #f97316;
--color-thv10-orange: oklch(0.7 0.19 45);
--color-thv10-coral: #fb923c;
--color-thv10-coral: oklch(0.76 0.15 55);
--color-thv10-crimson: #dc2626;
--color-thv10-crimson: oklch(0.58 0.22 27);
--font-thv10-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-10 {
width: 100%;
min-height: 100svh;
}
.thv-10 ::selection {
background: var(--color-thv10-crimson);
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 Fill Wipe Button Hover Effect
Source: https://codefronts.com/motion/tailwind-css-hover-effects/tailwind-fill-wipe-button-hover-effect/
Six directional fills — left wipe, diagonal slash, radial burst, curtain drop, centre split and an inset flood. One pattern, six origin-* and transform pairings, which is exactly the kind of variation utilities are good at.
## HTML
```html
<section class="thv-10 w-full min-h-svh grid place-items-center bg-thv10-bg font-thv10-sans px-6 py-14">
<div class="w-[min(860px,100%)] grid grid-cols-[repeat(auto-fit,minmax(230px,1fr))] gap-9">
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-red bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-red cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-red before:origin-left before:scale-x-0 before:transition-transform before:duration-350 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-x-100 focus-visible:text-white focus-visible:before:scale-x-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-red motion-reduce:before:transition-none"><span class="relative z-10">Left Wipe</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scaleX from left</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-rose bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-rose cursor-pointer transition-colors duration-400 before:content-[''] before:absolute before:-inset-[20%] before:-z-10 before:bg-thv10-rose before:origin-left before:-skew-x-[25deg] before:scale-x-0 before:transition-transform before:duration-500 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-x-100 focus-visible:text-white focus-visible:before:scale-x-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-rose motion-reduce:before:transition-none"><span class="relative z-10">Diagonal Slash</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">skew + scaleX</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-orange bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-orange cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-orange before:rounded-full before:scale-0 before:transition-transform before:duration-450 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-[3] focus-visible:text-white focus-visible:before:scale-[3] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-orange motion-reduce:before:transition-none"><span class="relative z-10">Radial Burst</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scale from center</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-coral bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-coral cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-coral before:origin-top before:scale-y-0 before:transition-transform before:duration-350 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-y-100 focus-visible:text-white focus-visible:before:scale-y-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-coral motion-reduce:before:transition-none"><span class="relative z-10">Curtain Drop</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scaleY from top</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="relative overflow-hidden isolate min-h-11 px-8 py-3 rounded-md border-2 border-thv10-crimson bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-crimson cursor-pointer transition-colors duration-350 before:content-[''] before:absolute before:inset-0 before:-z-10 before:bg-thv10-crimson before:origin-center before:scale-x-0 before:transition-transform before:duration-350 before:ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:before:scale-x-100 focus-visible:text-white focus-visible:before:scale-x-100 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-crimson motion-reduce:before:transition-none"><span class="relative z-10">Center Split</span></button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">scaleX outward</span>
</div>
<div class="flex flex-col items-center gap-5 px-5 py-10 rounded-xl bg-white/[0.025] border border-white/[0.07]">
<button type="button" class="min-h-11 px-8 py-3 rounded-md border-2 border-thv10-red bg-transparent text-[0.95rem] font-semibold tracking-[0.05em] text-thv10-red cursor-pointer shadow-[inset_0_0_0_0_var(--color-thv10-red)] transition-[box-shadow,color] duration-400 ease-[cubic-bezier(.4,0,.2,1)] hover:text-white hover:shadow-[inset_0_0_0_60px_var(--color-thv10-red)] focus-visible:text-white focus-visible:shadow-[inset_0_0_0_60px_var(--color-thv10-red)] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-thv10-red motion-reduce:transition-none">Inset Grow</button>
<span class="text-[11px] tracking-[0.12em] uppercase text-thv10-dim">box-shadow inset fill</span>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-thv10-bg: #0f0400;
--color-thv10-bg: oklch(0.13 0.03 40);
--color-thv10-dim: #6b7280;
--color-thv10-dim: oklch(0.55 0.02 265);
--color-thv10-red: #ef4444;
--color-thv10-red: oklch(0.64 0.21 25);
--color-thv10-rose: #f43f5e;
--color-thv10-rose: oklch(0.65 0.23 16);
--color-thv10-orange: #f97316;
--color-thv10-orange: oklch(0.7 0.19 45);
--color-thv10-coral: #fb923c;
--color-thv10-coral: oklch(0.76 0.15 55);
--color-thv10-crimson: #dc2626;
--color-thv10-crimson: oklch(0.58 0.22 27);
--font-thv10-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-10 {
width: 100%;
min-height: 100svh;
}
.thv-10 ::selection {
background: var(--color-thv10-crimson);
color: #fff;
}
```How this works
Six variants, one skeleton. Every button is relative overflow-hidden with before:absolute before:inset-0 before:-z-10 and a label at relative z-10. The only difference between left wipe, curtain drop and centre split is origin-left vs origin-top vs origin-center, and scale-x-0 vs scale-y-0.
Transforms compose in a single utility set. Tailwind's transform utilities all feed one transform declaration, so before:-skew-x-[25deg] before:scale-x-0 and hover:before:scale-x-100 compose correctly without restating the skew — the CSS version had to write transform: skewX(-25deg) scaleX(1) in full on hover.
The inset flood is the cheapest of the six. No pseudo-element, no clipping: a box-shadow spread grows from 0 to 60px and paints the button from the edges in.
Make it yours
- Swap the solid for a gradient:
before:bg-[linear-gradient(135deg,var(--color-thv10-red),var(--color-thv10-orange))]. - Morph the shape as it fills by adding
hover:rounded-noneto a pill. - Pair the fill with a
hover:scale-[1.03]on the button for fill-plus-lift.
Gotchas — read before shipping
- Always pair
before:-z-10withrelative z-10on the label, or the fill paints over the text. - The diagonal needs
overflow-hidden; without it the skewed rectangle hangs outside the button. - Flip the text colour in the same rule set as the fill (
hover:text-white) or the label disappears into the fill mid-sweep.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Baseline transforms and shadows; the floor is Tailwind v4's generated sheet.