36 Tailwind CSS Button Hover Effects
24 / 36

All 36 in 36 Tailwind CSS Button Hover Effects

  1. 01Tailwind Magnetic Ripple Attraction Button Hover Effect
  2. 02Tailwind Cyberpunk Holographic Glitch Grid Button
  3. 03Tailwind Frosted Glassmorphism Shimmer Glow Button
  4. 04Tailwind Organic Blob Morph Button Hover Effect
  5. 05Tailwind Dual-Line Intersection Border Draw Button
  6. 06Tailwind Isometric Tactile 3D Depress Button
  7. 07Tailwind Infinite Sliding Kinetic Marquee Button
  8. 08Tailwind Chroma Conic Gradient Border Spin Button
  9. 09Tailwind Minimalist Border & Outline Drawing Hover Effects
  10. 10Tailwind Modern 3D Skeuomorphic Button Press Effects
  11. 11Tailwind Neo-Brutalist & Cyberpunk Button Glow Effects
  12. 12Tailwind Sliding Background Color Wipe Button Effects
  13. 13Tailwind Liquid Fill & Organic Morphing Button Effects
  14. 14Tailwind Kinetic Text Flip & Icon Reveal Button Effects
  15. 15Tailwind Liquid Wave Fill Button Hover Effect
  16. 16Tailwind Magnetic Border Drift Button
  17. 17Tailwind Glitch Slice Button Hover Effect
  18. 18Tailwind Neon Pulse Glow Button Hover Effect
  19. 19Tailwind Split Reveal Curtain Button Effect
  20. 20Tailwind Diagonal Shutter Sweep Button Effect
  21. 21Tailwind Elastic Lift Spring Button Hover Effect
  22. 22Tailwind Center Underline Draw Link Button Effects
  23. 23Tailwind 3D Flip Card Button Hover Effect
  24. 24Tailwind Particle Burst Confetti Button Effect
  25. 25Tailwind Slide Doors Closing Panel Button Effect
  26. 26Tailwind Typewriter Retype Terminal Button Effect
  27. 27Tailwind Hard Shadow Shift Flat Button Effect
  28. 28Tailwind Material Ripple Wave Button Effect
  29. 29Tailwind Rainbow Gradient Border Spin Button
  30. 30Tailwind Morph Shape Silhouette Button Effects
  31. 31Tailwind Icon Slide In Directional Button Effect
  32. 32Tailwind Cursor Spotlight Glow Button
  33. 33Tailwind Stagger Fill Equaliser Button Effect
  34. 34Tailwind Sunburst Expand Radiant Button Effect
  35. 35Tailwind 3D Press Plunger Key Button Effect
  36. 36Tailwind Add-to-Cart Liquid Glass Ripple Button
Pure TailwindMIT licensed

Tailwind Particle Burst Confetti Button Effect

A celebratory CTA that scatters particles outward on hover — confetti-style points fly out and fade. Every particle is a box-shadow clone of one 6px dot, which means eight particles cost one element and zero extra DOM.

Live Demo
Plain CSSTailwind v4
Try it

Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time

Untitled UI React · Affiliate link

Get Untitled UI Pro

The code

<div class="tbh-24-group w-full min-h-svh flex flex-wrap">
<section class="tbh-24a flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh24-sans bg-tbh24a-stage" aria-label="Particle burst button">
  <button type="button" class="group/btn relative overflow-visible cursor-pointer border-0 rounded-full px-[42px] py-4 text-base font-extrabold text-white bg-tbh24a-acc focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-4">
    <span aria-hidden="true" class="absolute left-1/2 top-1/2 w-1.5 h-1.5 rounded-full bg-tbh24a-p4 opacity-0 pointer-events-none shadow-[34px_-18px_var(--color-tbh24a-p1),-40px_-10px_var(--color-tbh24a-p2),54px_12px_var(--color-tbh24a-p3),-30px_20px_var(--color-tbh24a-p4)] group-hover/btn:animate-tbh24a-burst group-focus-visible/btn:animate-tbh24a-burst motion-reduce:group-hover/btn:animate-none"></span>
    <span aria-hidden="true" class="absolute left-1/2 top-1/2 w-1.5 h-1.5 rounded-full bg-tbh24a-p2 opacity-0 pointer-events-none shadow-[20px_-30px_var(--color-tbh24a-p2),-52px_6px_var(--color-tbh24a-p4),44px_26px_var(--color-tbh24a-p1),-18px_-26px_var(--color-tbh24a-p3)] group-hover/btn:animate-tbh24a-burst group-focus-visible/btn:animate-tbh24a-burst motion-reduce:group-hover/btn:animate-none"></span>
    <span class="relative z-[1]">Like</span>
  </button>
</section>
<section class="tbh-24b flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh24-sans bg-tbh24b-stage" aria-label="Spark ring button">
  <button type="button" class="group/btn relative overflow-visible cursor-pointer border-0 rounded-full px-[42px] py-4 text-base font-extrabold text-tbh24b-ink bg-tbh24b-acc focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-4">
    <span aria-hidden="true" class="absolute left-1/2 top-1/2 -ml-1 -mt-1 w-2 h-2 rounded-full bg-transparent opacity-0 scale-[.3] pointer-events-none shadow-[0_-34px_var(--color-tbh24b-acc),24px_-24px_var(--color-tbh24b-acc),34px_0_var(--color-tbh24b-acc),24px_24px_var(--color-tbh24b-acc),0_34px_var(--color-tbh24b-acc),-24px_24px_var(--color-tbh24b-acc),-34px_0_var(--color-tbh24b-acc),-24px_-24px_var(--color-tbh24b-acc)] group-hover/btn:animate-tbh24b-spark group-focus-visible/btn:animate-tbh24b-spark motion-reduce:group-hover/btn:animate-none"></span>
    <span class="relative z-[1]">Boost</span>
  </button>
</section>
</div>
@import "tailwindcss";

@theme {
  --color-tbh24a-acc: #e0492f;
  --color-tbh24a-acc: oklch(0.62 0.22 20);
  --color-tbh24a-p1: #ff7ab6;
  --color-tbh24a-p1: oklch(0.78 0.16 350);
  --color-tbh24a-p2: #7ce0ff;
  --color-tbh24a-p2: oklch(0.87 0.11 215);
  --color-tbh24a-p3: #b6ff7a;
  --color-tbh24a-p3: oklch(0.92 0.18 130);
  --color-tbh24a-p4: #ffd15c;
  --color-tbh24a-p4: oklch(0.87 0.15 90);
  --color-tbh24a-stage: #120a0e;
  --color-tbh24a-stage: oklch(0.15 0.02 20);
  --color-tbh24b-acc: #e0b04a;
  --color-tbh24b-acc: oklch(0.78 0.15 90);
  --color-tbh24b-ink: #1a1206;
  --color-tbh24b-ink: oklch(0.22 0.04 85);
  --color-tbh24b-stage: #14100a;
  --color-tbh24b-stage: oklch(0.16 0.02 85);
  --font-tbh24-sans: 'Space Grotesk', system-ui, sans-serif;
  --animate-tbh24a-burst: tbh24a-burst 0.6s ease-out;
  --animate-tbh24b-spark: tbh24b-spark 0.55s ease-out;
}
/* Stays CSS: two one-shot keyframes. Both hold the -50% centring in translate and animate
   only scale and opacity, so the utilities and the keyframe never fight over a property. */

@keyframes tbh24a-burst {
  0% {
    opacity: 1;
    translate: -50% -50%;
    scale: 0.2;
  }

  100% {
    opacity: 0;
    translate: -50% -50%;
    scale: 1.6;
  }
}

@keyframes tbh24b-spark {
  0% {
    opacity: 1;
    scale: 0.3;
  }

  100% {
    opacity: 0;
    scale: 1.5;
  }
}

.tbh-24-group {
  width: 100%;
  min-height: 100svh;
}

.tbh-24a,
.tbh-24b {
  min-height: 100svh;
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<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.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-tbh24a-acc: #e0492f;
  --color-tbh24a-acc: oklch(0.62 0.22 20);
  --color-tbh24a-p1: #ff7ab6;
  --color-tbh24a-p1: oklch(0.78 0.16 350);
  --color-tbh24a-p2: #7ce0ff;
  --color-tbh24a-p2: oklch(0.87 0.11 215);
  --color-tbh24a-p3: #b6ff7a;
  --color-tbh24a-p3: oklch(0.92 0.18 130);
  --color-tbh24a-p4: #ffd15c;
  --color-tbh24a-p4: oklch(0.87 0.15 90);
  --color-tbh24a-stage: #120a0e;
  --color-tbh24a-stage: oklch(0.15 0.02 20);
  --color-tbh24b-acc: #e0b04a;
  --color-tbh24b-acc: oklch(0.78 0.15 90);
  --color-tbh24b-ink: #1a1206;
  --color-tbh24b-ink: oklch(0.22 0.04 85);
  --color-tbh24b-stage: #14100a;
  --color-tbh24b-stage: oklch(0.16 0.02 85);
  --font-tbh24-sans: 'Space Grotesk', system-ui, sans-serif;
  --animate-tbh24a-burst: tbh24a-burst 0.6s ease-out;
  --animate-tbh24b-spark: tbh24b-spark 0.55s ease-out;
}
/* Stays CSS: two one-shot keyframes. Both hold the -50% centring in translate and animate
   only scale and opacity, so the utilities and the keyframe never fight over a property. */

@keyframes tbh24a-burst {
  0% {
    opacity: 1;
    translate: -50% -50%;
    scale: 0.2;
  }

  100% {
    opacity: 0;
    translate: -50% -50%;
    scale: 1.6;
  }
}

@keyframes tbh24b-spark {
  0% {
    opacity: 1;
    scale: 0.3;
  }

  100% {
    opacity: 0;
    scale: 1.5;
  }
}

.tbh-24-group {
  width: 100%;
  min-height: 100svh;
}

.tbh-24a,
.tbh-24b {
  min-height: 100svh;
}
3Fonts used by this demooptional — skip if you have your own type stack
<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 box-shadow-as-particles technique ports verbatim into one long arbitrary shadow-[...] value, and promoting the four particle colours to @theme tokens means the palette is editable in one place instead of being eight inline hexes.
  • Both keyframes were rewritten to hold the centring in translate and animate only scale/opacity — in the CSS original the keyframe restated translate(-50%,-50%) inside a compound transform on every stop.
  • UI change from the CSS original: the burst now also fires on group-focus-visible/btn:, so keyboard users get the celebration too — and both stages darkened slightly so the pastel particles read at full contrast.
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
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 Particle Burst Confetti Button Effect
Source: https://codefronts.com/motion/tailwind-css-button-hover-effects/tailwind-particle-burst-confetti-button-effect/

A celebratory CTA that scatters particles outward on hover &mdash; confetti-style points fly out and fade. Every particle is a box-shadow clone of one 6px dot, which means eight particles cost one element and zero extra DOM.
## HTML
```html
<div class="tbh-24-group w-full min-h-svh flex flex-wrap">
<section class="tbh-24a flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh24-sans bg-tbh24a-stage" aria-label="Particle burst button">
  <button type="button" class="group/btn relative overflow-visible cursor-pointer border-0 rounded-full px-[42px] py-4 text-base font-extrabold text-white bg-tbh24a-acc focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-4">
    <span aria-hidden="true" class="absolute left-1/2 top-1/2 w-1.5 h-1.5 rounded-full bg-tbh24a-p4 opacity-0 pointer-events-none shadow-[34px_-18px_var(--color-tbh24a-p1),-40px_-10px_var(--color-tbh24a-p2),54px_12px_var(--color-tbh24a-p3),-30px_20px_var(--color-tbh24a-p4)] group-hover/btn:animate-tbh24a-burst group-focus-visible/btn:animate-tbh24a-burst motion-reduce:group-hover/btn:animate-none"></span>
    <span aria-hidden="true" class="absolute left-1/2 top-1/2 w-1.5 h-1.5 rounded-full bg-tbh24a-p2 opacity-0 pointer-events-none shadow-[20px_-30px_var(--color-tbh24a-p2),-52px_6px_var(--color-tbh24a-p4),44px_26px_var(--color-tbh24a-p1),-18px_-26px_var(--color-tbh24a-p3)] group-hover/btn:animate-tbh24a-burst group-focus-visible/btn:animate-tbh24a-burst motion-reduce:group-hover/btn:animate-none"></span>
    <span class="relative z-[1]">Like</span>
  </button>
</section>
<section class="tbh-24b flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh24-sans bg-tbh24b-stage" aria-label="Spark ring button">
  <button type="button" class="group/btn relative overflow-visible cursor-pointer border-0 rounded-full px-[42px] py-4 text-base font-extrabold text-tbh24b-ink bg-tbh24b-acc focus-visible:outline-3 focus-visible:outline-white focus-visible:outline-offset-4">
    <span aria-hidden="true" class="absolute left-1/2 top-1/2 -ml-1 -mt-1 w-2 h-2 rounded-full bg-transparent opacity-0 scale-[.3] pointer-events-none shadow-[0_-34px_var(--color-tbh24b-acc),24px_-24px_var(--color-tbh24b-acc),34px_0_var(--color-tbh24b-acc),24px_24px_var(--color-tbh24b-acc),0_34px_var(--color-tbh24b-acc),-24px_24px_var(--color-tbh24b-acc),-34px_0_var(--color-tbh24b-acc),-24px_-24px_var(--color-tbh24b-acc)] group-hover/btn:animate-tbh24b-spark group-focus-visible/btn:animate-tbh24b-spark motion-reduce:group-hover/btn:animate-none"></span>
    <span class="relative z-[1]">Boost</span>
  </button>
</section>
</div>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tbh24a-acc: #e0492f;
  --color-tbh24a-acc: oklch(0.62 0.22 20);
  --color-tbh24a-p1: #ff7ab6;
  --color-tbh24a-p1: oklch(0.78 0.16 350);
  --color-tbh24a-p2: #7ce0ff;
  --color-tbh24a-p2: oklch(0.87 0.11 215);
  --color-tbh24a-p3: #b6ff7a;
  --color-tbh24a-p3: oklch(0.92 0.18 130);
  --color-tbh24a-p4: #ffd15c;
  --color-tbh24a-p4: oklch(0.87 0.15 90);
  --color-tbh24a-stage: #120a0e;
  --color-tbh24a-stage: oklch(0.15 0.02 20);
  --color-tbh24b-acc: #e0b04a;
  --color-tbh24b-acc: oklch(0.78 0.15 90);
  --color-tbh24b-ink: #1a1206;
  --color-tbh24b-ink: oklch(0.22 0.04 85);
  --color-tbh24b-stage: #14100a;
  --color-tbh24b-stage: oklch(0.16 0.02 85);
  --font-tbh24-sans: 'Space Grotesk', system-ui, sans-serif;
  --animate-tbh24a-burst: tbh24a-burst 0.6s ease-out;
  --animate-tbh24b-spark: tbh24b-spark 0.55s ease-out;
}
/* Stays CSS: two one-shot keyframes. Both hold the -50% centring in translate and animate
   only scale and opacity, so the utilities and the keyframe never fight over a property. */

@keyframes tbh24a-burst {
  0% {
    opacity: 1;
    translate: -50% -50%;
    scale: 0.2;
  }

  100% {
    opacity: 0;
    translate: -50% -50%;
    scale: 1.6;
  }
}

@keyframes tbh24b-spark {
  0% {
    opacity: 1;
    scale: 0.3;
  }

  100% {
    opacity: 0;
    scale: 1.5;
  }
}

.tbh-24-group {
  width: 100%;
  min-height: 100svh;
}

.tbh-24a,
.tbh-24b {
  min-height: 100svh;
}
```

How this works

One element, many particles. A box-shadow list renders arbitrarily many copies of an element's shape at arbitrary offsets and colours. Scaling the element scales every clone away from the origin at once, which is the entire burst — no per-particle animation, no JS, no extra nodes.

The animation is one-shot. No infinite: the keyframe runs once per hover, which is what makes it feel like a reaction rather than an ambience. Re-hovering replays it because the animation is applied by the hover variant.

Overflow must stay visible. This is the one demo in the collection that explicitly does NOT clip: overflow-visible lets the particles leave the button. Everything else about the pattern depends on that.

Make it yours

  • Particle count: extend the shadow-[...] clone list — each entry is one more particle at no DOM cost.
  • Palette: the four --color-tbh24a-p* tokens; varying hue AND offset is what keeps it from looking mechanical.
  • Reach: the scale-[1.6] end stop in the burst keyframe.
  • Trigger on click instead: move the animation from group-hover/btn: to group-active/btn: for a like-button feel.

Gotchas — read before shipping

  • Keep the clone count sensible. Each one is a real paint; a 30-particle burst on a list of buttons will show up in INP.
  • Particles need pointer-events-none — they extend past the button and would otherwise create dead click zones around it.
  • overflow-visible on the button is required, which means this effect cannot be combined with any of the clipped fills in this collection.
  • Use a one-shot animation, not infinite. A looping confetti burst reads as a broken loading state.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

Multi-value box-shadow and keyframes are universal; with animation unavailable the particles simply never appear (they rest at opacity-0).

Techniques used in this demo

Utilitiesfirst-class utility or variant

Plain CSSno Tailwind surface

Search CodeFronts

Loading…