08 / 20
All 20 in 20 Tailwind CSS Animated Buttons
- 01Tailwind Neon Glow Button with Pulsing Halo
- 02Tailwind Background Slide Hover Button (Four Directions)
- 03Tailwind Ripple Effect Button with No JavaScript
- 04Tailwind Animated Border Draw Button with Staged Delays
- 05Tailwind 3D Press Effect Button with Keycap Depth
- 06Tailwind Liquid Fill Button with Animated Wave Crest
- 07Tailwind Moving Gradient CTA Button
- 08Tailwind Shine Sweep Hover Button with Gloss Streak
- 09Tailwind Jelly Bounce Button with Elastic Squash
- 10Tailwind Text Flip Button Hover with 3D Rotation
- 11Tailwind Animated CTA Hero Button with Beacon Rings & Particle Burst
- 12Tailwind Submit Button Success State with Checkmark Draw
- 13Tailwind Animated Download Button with Progress Fill
- 14Tailwind Hamburger to Close Button with aria-expanded Variants
- 15Tailwind Add to Cart Button with Flying Product Dot
- 16Tailwind Social Share Buttons with Brand Hover & Copy Link
- 17Tailwind Animated Toggle Switch with peer-checked & has-checked
- 18Tailwind Loading Spinner Inside Button with State Machine
- 19Tailwind Next & Prev Arrow Buttons with Chasing Icons
- 20Tailwind Ghost Button with Cursor-Aware Background Reveal
Tailwind Shine Sweep Hover Button with Gloss Streak
A narrow band of light crosses the button face once per hover. The port puts the streak's whole identity — gradient, tilt, starting position — on the element as before: utilities, and its motion in one hover:before:animate-tab08-shine.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tab-08 w-full min-h-svh grid place-items-center bg-tab08-bg font-tab08-sans px-6 py-10">
<div class="flex flex-col items-center gap-8">
<p class="text-[0.78rem] tracking-[0.14em] uppercase text-tab08-mut m-0">Hover over the buttons</p>
<div class="flex flex-wrap justify-center gap-4">
<button type="button" class="relative overflow-hidden min-h-11 px-9 text-[0.95rem] font-bold tracking-[0.04em] text-tab08-ink bg-tab08-slate rounded-[10px] cursor-pointer transition-[translate,filter] duration-150 hover:brightness-110 hover:-translate-y-0.5 active:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab08-slate before:content-[''] before:absolute before:-top-[10%] before:-left-[20%] before:w-[60%] before:h-[120%] before:bg-[linear-gradient(105deg,transparent_30%,oklch(1_0_0/0.55)_50%,transparent_70%)] before:-skew-x-[15deg] before:-translate-x-full before:pointer-events-none hover:before:animate-tab08-shine focus-visible:before:animate-tab08-shine motion-reduce:hover:before:animate-none motion-reduce:transition-none">Pro Features</button>
<button type="button" class="relative overflow-hidden min-h-11 px-9 text-[0.95rem] font-bold tracking-[0.04em] text-white bg-[linear-gradient(135deg,#b45309,#d97706,#fbbf24)] rounded-[10px] cursor-pointer transition-[translate,filter] duration-150 hover:brightness-110 hover:-translate-y-0.5 active:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab08-gold before:content-[''] before:absolute before:-top-[10%] before:-left-[20%] before:w-[60%] before:h-[120%] before:bg-[linear-gradient(105deg,transparent_30%,oklch(1_0_0/0.55)_50%,transparent_70%)] before:-skew-x-[15deg] before:-translate-x-full before:pointer-events-none hover:before:animate-tab08-shine focus-visible:before:animate-tab08-shine motion-reduce:hover:before:animate-none motion-reduce:transition-none">Upgrade Now</button>
<button type="button" class="relative overflow-hidden min-h-11 px-9 text-[0.95rem] font-bold tracking-[0.04em] text-white bg-[linear-gradient(135deg,#4c1d95,#7c3aed,#a78bfa)] rounded-[10px] cursor-pointer transition-[translate,filter] duration-150 hover:brightness-110 hover:-translate-y-0.5 active:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab08-violet before:content-[''] before:absolute before:-top-[10%] before:-left-[20%] before:w-[60%] before:h-[120%] before:bg-[linear-gradient(105deg,transparent_30%,oklch(1_0_0/0.55)_50%,transparent_70%)] before:-skew-x-[15deg] before:-translate-x-full before:pointer-events-none hover:before:animate-tab08-shine focus-visible:before:animate-tab08-shine motion-reduce:hover:before:animate-none motion-reduce:transition-none">Get Premium</button>
</div>
</div>
</section><section class="tab-08 w-full min-h-svh grid place-items-center bg-tab08-bg font-tab08-sans px-6 py-10">
<div class="flex flex-col items-center gap-8">
<p class="text-[0.78rem] tracking-[0.14em] uppercase text-tab08-mut m-0">Hover over the buttons</p>
<div class="flex flex-wrap justify-center gap-4">
<button type="button" class="relative overflow-hidden min-h-11 px-9 text-[0.95rem] font-bold tracking-[0.04em] text-tab08-ink bg-tab08-slate rounded-[10px] cursor-pointer transition-[translate,filter] duration-150 hover:brightness-110 hover:-translate-y-0.5 active:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab08-slate before:content-[''] before:absolute before:-top-[10%] before:-left-[20%] before:w-[60%] before:h-[120%] before:bg-[linear-gradient(105deg,transparent_30%,oklch(1_0_0/0.55)_50%,transparent_70%)] before:-skew-x-[15deg] before:-translate-x-full before:pointer-events-none hover:before:animate-tab08-shine focus-visible:before:animate-tab08-shine motion-reduce:hover:before:animate-none motion-reduce:transition-none">Pro Features</button>
<button type="button" class="relative overflow-hidden min-h-11 px-9 text-[0.95rem] font-bold tracking-[0.04em] text-white bg-[linear-gradient(135deg,#b45309,#d97706,#fbbf24)] rounded-[10px] cursor-pointer transition-[translate,filter] duration-150 hover:brightness-110 hover:-translate-y-0.5 active:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab08-gold before:content-[''] before:absolute before:-top-[10%] before:-left-[20%] before:w-[60%] before:h-[120%] before:bg-[linear-gradient(105deg,transparent_30%,oklch(1_0_0/0.55)_50%,transparent_70%)] before:-skew-x-[15deg] before:-translate-x-full before:pointer-events-none hover:before:animate-tab08-shine focus-visible:before:animate-tab08-shine motion-reduce:hover:before:animate-none motion-reduce:transition-none">Upgrade Now</button>
<button type="button" class="relative overflow-hidden min-h-11 px-9 text-[0.95rem] font-bold tracking-[0.04em] text-white bg-[linear-gradient(135deg,#4c1d95,#7c3aed,#a78bfa)] rounded-[10px] cursor-pointer transition-[translate,filter] duration-150 hover:brightness-110 hover:-translate-y-0.5 active:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab08-violet before:content-[''] before:absolute before:-top-[10%] before:-left-[20%] before:w-[60%] before:h-[120%] before:bg-[linear-gradient(105deg,transparent_30%,oklch(1_0_0/0.55)_50%,transparent_70%)] before:-skew-x-[15deg] before:-translate-x-full before:pointer-events-none hover:before:animate-tab08-shine focus-visible:before:animate-tab08-shine motion-reduce:hover:before:animate-none motion-reduce:transition-none">Get Premium</button>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-tab08-bg: #f1f5f9;
--color-tab08-bg: oklch(0.97 0.006 250);
--color-tab08-mut: #64748b;
--color-tab08-mut: oklch(0.55 0.03 255);
--color-tab08-slate: #1e293b;
--color-tab08-slate: oklch(0.28 0.03 258);
--color-tab08-ink: #e2e8f0;
--color-tab08-ink: oklch(0.92 0.01 250);
--color-tab08-gold: #b45309;
--color-tab08-gold: oklch(0.53 0.15 62);
--color-tab08-violet: #4c1d95;
--color-tab08-violet: oklch(0.36 0.2 296);
--font-tab08-sans: 'Space Grotesk', system-ui, sans-serif;
--animate-tab08-shine: tab08-shine 0.55s ease-in-out forwards;
}
@keyframes tab08-shine {
0% {
translate: -100% 0;
}
100% {
translate: 400% 0;
}
}
.tab-08 {
width: 100%;
min-height: 100svh;
}
.tab-08 ::selection {
background: var(--color-tab08-slate);
color: #fff;
}@import "tailwindcss";
@theme {
--color-tab08-bg: #f1f5f9;
--color-tab08-bg: oklch(0.97 0.006 250);
--color-tab08-mut: #64748b;
--color-tab08-mut: oklch(0.55 0.03 255);
--color-tab08-slate: #1e293b;
--color-tab08-slate: oklch(0.28 0.03 258);
--color-tab08-ink: #e2e8f0;
--color-tab08-ink: oklch(0.92 0.01 250);
--color-tab08-gold: #b45309;
--color-tab08-gold: oklch(0.53 0.15 62);
--color-tab08-violet: #4c1d95;
--color-tab08-violet: oklch(0.36 0.2 296);
--font-tab08-sans: 'Space Grotesk', system-ui, sans-serif;
--animate-tab08-shine: tab08-shine 0.55s ease-in-out forwards;
}
@keyframes tab08-shine {
0% {
translate: -100% 0;
}
100% {
translate: 400% 0;
}
}
.tab-08 {
width: 100%;
min-height: 100svh;
}
.tab-08 ::selection {
background: var(--color-tab08-slate);
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-tab08-bg: #f1f5f9;
--color-tab08-bg: oklch(0.97 0.006 250);
--color-tab08-mut: #64748b;
--color-tab08-mut: oklch(0.55 0.03 255);
--color-tab08-slate: #1e293b;
--color-tab08-slate: oklch(0.28 0.03 258);
--color-tab08-ink: #e2e8f0;
--color-tab08-ink: oklch(0.92 0.01 250);
--color-tab08-gold: #b45309;
--color-tab08-gold: oklch(0.53 0.15 62);
--color-tab08-violet: #4c1d95;
--color-tab08-violet: oklch(0.36 0.2 296);
--font-tab08-sans: 'Space Grotesk', system-ui, sans-serif;
--animate-tab08-shine: tab08-shine 0.55s ease-in-out forwards;
}
@keyframes tab08-shine {
0% {
translate: -100% 0;
}
100% {
translate: 400% 0;
}
}
.tab-08 {
width: 100%;
min-height: 100svh;
}
.tab-08 ::selection {
background: var(--color-tab08-slate);
color: #fff;
}@import "tailwindcss";
@theme {
--color-tab08-bg: #f1f5f9;
--color-tab08-bg: oklch(0.97 0.006 250);
--color-tab08-mut: #64748b;
--color-tab08-mut: oklch(0.55 0.03 255);
--color-tab08-slate: #1e293b;
--color-tab08-slate: oklch(0.28 0.03 258);
--color-tab08-ink: #e2e8f0;
--color-tab08-ink: oklch(0.92 0.01 250);
--color-tab08-gold: #b45309;
--color-tab08-gold: oklch(0.53 0.15 62);
--color-tab08-violet: #4c1d95;
--color-tab08-violet: oklch(0.36 0.2 296);
--font-tab08-sans: 'Space Grotesk', system-ui, sans-serif;
--animate-tab08-shine: tab08-shine 0.55s ease-in-out forwards;
}
@keyframes tab08-shine {
0% {
translate: -100% 0;
}
100% {
translate: 400% 0;
}
}
.tab-08 {
width: 100%;
min-height: 100svh;
}
.tab-08 ::selection {
background: var(--color-tab08-slate);
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&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.
- The keyframe animates the
translateproperty, nottransform, so it composes with the-skew-x-*utility instead of overwriting it. That is the v4-native way to mix a utility transform with a keyframed one. - The streak's gradient stays an arbitrary utility rather than a token: it is one decorative composite, not a reusable colour.
- UI change from the CSS original: the sweep now also fires on
focus-visible, so the premium cue is not reserved for pointer users.
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 Shine Sweep Hover Button with Gloss Streak
Source: https://codefronts.com/motion/tailwind-css-animated-buttons/tailwind-shine-sweep-hover-button/
A narrow band of light crosses the button face once per hover. The port puts the streak's whole identity — gradient, tilt, starting position — on the element as before: utilities, and its motion in one hover:before:animate-tab08-shine.
## HTML
```html
<section class="tab-08 w-full min-h-svh grid place-items-center bg-tab08-bg font-tab08-sans px-6 py-10">
<div class="flex flex-col items-center gap-8">
<p class="text-[0.78rem] tracking-[0.14em] uppercase text-tab08-mut m-0">Hover over the buttons</p>
<div class="flex flex-wrap justify-center gap-4">
<button type="button" class="relative overflow-hidden min-h-11 px-9 text-[0.95rem] font-bold tracking-[0.04em] text-tab08-ink bg-tab08-slate rounded-[10px] cursor-pointer transition-[translate,filter] duration-150 hover:brightness-110 hover:-translate-y-0.5 active:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab08-slate before:content-[''] before:absolute before:-top-[10%] before:-left-[20%] before:w-[60%] before:h-[120%] before:bg-[linear-gradient(105deg,transparent_30%,oklch(1_0_0/0.55)_50%,transparent_70%)] before:-skew-x-[15deg] before:-translate-x-full before:pointer-events-none hover:before:animate-tab08-shine focus-visible:before:animate-tab08-shine motion-reduce:hover:before:animate-none motion-reduce:transition-none">Pro Features</button>
<button type="button" class="relative overflow-hidden min-h-11 px-9 text-[0.95rem] font-bold tracking-[0.04em] text-white bg-[linear-gradient(135deg,#b45309,#d97706,#fbbf24)] rounded-[10px] cursor-pointer transition-[translate,filter] duration-150 hover:brightness-110 hover:-translate-y-0.5 active:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab08-gold before:content-[''] before:absolute before:-top-[10%] before:-left-[20%] before:w-[60%] before:h-[120%] before:bg-[linear-gradient(105deg,transparent_30%,oklch(1_0_0/0.55)_50%,transparent_70%)] before:-skew-x-[15deg] before:-translate-x-full before:pointer-events-none hover:before:animate-tab08-shine focus-visible:before:animate-tab08-shine motion-reduce:hover:before:animate-none motion-reduce:transition-none">Upgrade Now</button>
<button type="button" class="relative overflow-hidden min-h-11 px-9 text-[0.95rem] font-bold tracking-[0.04em] text-white bg-[linear-gradient(135deg,#4c1d95,#7c3aed,#a78bfa)] rounded-[10px] cursor-pointer transition-[translate,filter] duration-150 hover:brightness-110 hover:-translate-y-0.5 active:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab08-violet before:content-[''] before:absolute before:-top-[10%] before:-left-[20%] before:w-[60%] before:h-[120%] before:bg-[linear-gradient(105deg,transparent_30%,oklch(1_0_0/0.55)_50%,transparent_70%)] before:-skew-x-[15deg] before:-translate-x-full before:pointer-events-none hover:before:animate-tab08-shine focus-visible:before:animate-tab08-shine motion-reduce:hover:before:animate-none motion-reduce:transition-none">Get Premium</button>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tab08-bg: #f1f5f9;
--color-tab08-bg: oklch(0.97 0.006 250);
--color-tab08-mut: #64748b;
--color-tab08-mut: oklch(0.55 0.03 255);
--color-tab08-slate: #1e293b;
--color-tab08-slate: oklch(0.28 0.03 258);
--color-tab08-ink: #e2e8f0;
--color-tab08-ink: oklch(0.92 0.01 250);
--color-tab08-gold: #b45309;
--color-tab08-gold: oklch(0.53 0.15 62);
--color-tab08-violet: #4c1d95;
--color-tab08-violet: oklch(0.36 0.2 296);
--font-tab08-sans: 'Space Grotesk', system-ui, sans-serif;
--animate-tab08-shine: tab08-shine 0.55s ease-in-out forwards;
}
@keyframes tab08-shine {
0% {
translate: -100% 0;
}
100% {
translate: 400% 0;
}
}
.tab-08 {
width: 100%;
min-height: 100svh;
}
.tab-08 ::selection {
background: var(--color-tab08-slate);
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 Shine Sweep Hover Button with Gloss Streak
Source: https://codefronts.com/motion/tailwind-css-animated-buttons/tailwind-shine-sweep-hover-button/
A narrow band of light crosses the button face once per hover. The port puts the streak's whole identity — gradient, tilt, starting position — on the element as before: utilities, and its motion in one hover:before:animate-tab08-shine.
## HTML
```html
<section class="tab-08 w-full min-h-svh grid place-items-center bg-tab08-bg font-tab08-sans px-6 py-10">
<div class="flex flex-col items-center gap-8">
<p class="text-[0.78rem] tracking-[0.14em] uppercase text-tab08-mut m-0">Hover over the buttons</p>
<div class="flex flex-wrap justify-center gap-4">
<button type="button" class="relative overflow-hidden min-h-11 px-9 text-[0.95rem] font-bold tracking-[0.04em] text-tab08-ink bg-tab08-slate rounded-[10px] cursor-pointer transition-[translate,filter] duration-150 hover:brightness-110 hover:-translate-y-0.5 active:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab08-slate before:content-[''] before:absolute before:-top-[10%] before:-left-[20%] before:w-[60%] before:h-[120%] before:bg-[linear-gradient(105deg,transparent_30%,oklch(1_0_0/0.55)_50%,transparent_70%)] before:-skew-x-[15deg] before:-translate-x-full before:pointer-events-none hover:before:animate-tab08-shine focus-visible:before:animate-tab08-shine motion-reduce:hover:before:animate-none motion-reduce:transition-none">Pro Features</button>
<button type="button" class="relative overflow-hidden min-h-11 px-9 text-[0.95rem] font-bold tracking-[0.04em] text-white bg-[linear-gradient(135deg,#b45309,#d97706,#fbbf24)] rounded-[10px] cursor-pointer transition-[translate,filter] duration-150 hover:brightness-110 hover:-translate-y-0.5 active:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab08-gold before:content-[''] before:absolute before:-top-[10%] before:-left-[20%] before:w-[60%] before:h-[120%] before:bg-[linear-gradient(105deg,transparent_30%,oklch(1_0_0/0.55)_50%,transparent_70%)] before:-skew-x-[15deg] before:-translate-x-full before:pointer-events-none hover:before:animate-tab08-shine focus-visible:before:animate-tab08-shine motion-reduce:hover:before:animate-none motion-reduce:transition-none">Upgrade Now</button>
<button type="button" class="relative overflow-hidden min-h-11 px-9 text-[0.95rem] font-bold tracking-[0.04em] text-white bg-[linear-gradient(135deg,#4c1d95,#7c3aed,#a78bfa)] rounded-[10px] cursor-pointer transition-[translate,filter] duration-150 hover:brightness-110 hover:-translate-y-0.5 active:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab08-violet before:content-[''] before:absolute before:-top-[10%] before:-left-[20%] before:w-[60%] before:h-[120%] before:bg-[linear-gradient(105deg,transparent_30%,oklch(1_0_0/0.55)_50%,transparent_70%)] before:-skew-x-[15deg] before:-translate-x-full before:pointer-events-none hover:before:animate-tab08-shine focus-visible:before:animate-tab08-shine motion-reduce:hover:before:animate-none motion-reduce:transition-none">Get Premium</button>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tab08-bg: #f1f5f9;
--color-tab08-bg: oklch(0.97 0.006 250);
--color-tab08-mut: #64748b;
--color-tab08-mut: oklch(0.55 0.03 255);
--color-tab08-slate: #1e293b;
--color-tab08-slate: oklch(0.28 0.03 258);
--color-tab08-ink: #e2e8f0;
--color-tab08-ink: oklch(0.92 0.01 250);
--color-tab08-gold: #b45309;
--color-tab08-gold: oklch(0.53 0.15 62);
--color-tab08-violet: #4c1d95;
--color-tab08-violet: oklch(0.36 0.2 296);
--font-tab08-sans: 'Space Grotesk', system-ui, sans-serif;
--animate-tab08-shine: tab08-shine 0.55s ease-in-out forwards;
}
@keyframes tab08-shine {
0% {
translate: -100% 0;
}
100% {
translate: 400% 0;
}
}
.tab-08 {
width: 100%;
min-height: 100svh;
}
.tab-08 ::selection {
background: var(--color-tab08-slate);
color: #fff;
}
```How this works
The streak is a gradient, not an image. Three stops — transparent, 55% white, transparent — give a soft-edged band. overflow-hidden clips it as it enters and leaves, so the button appears to have a gloss surface rather than a moving child.
Skew is a utility; translate is the keyframe. Tailwind's -skew-x-* composes with the keyframe's translateX because v4 writes transforms through individual custom properties — something the CSS original had to do by repeating skewX(-15deg) in both keyframe steps.
Re-trigger on re-entry is free. Leaving the button removes :hover, which unbinds the animation; the next entry starts it from frame zero. No JS, no class toggling.
Make it yours
- Wider flash: widen the gradient's middle band from
30%…70%to20%…80%. - Steeper cut:
-skew-x-[15deg]→-skew-x-[30deg]. - Gold gloss: replace the white stop with
oklch(0.9_0.13_90/0.55).
Gotchas — read before shipping
- Fast pointer oscillation at the button edge can restart the sweep mid-pass. It is inherent to hover-triggered animations; a JS class toggle is the only fix and is rarely worth it.
- On iOS,
:hoversticks after a tap, so the streak plays once and stays parked — acceptable, but do not build meaning into the sweep. overflow-hiddenclipsshadow-*too. The lift here usestranslateonly, for exactly that reason.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Gradients and transform animations are universally supported; the floor is Tailwind v4's generated sheet.