36 Tailwind CSS Button Hover Effects
21 / 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 Elastic Lift Spring Button Hover Effect

A bouncy, delightful CTA that springs up on hover — it lifts, squashes slightly and overshoots before settling. The squash is the part most implementations skip, and in v4 it is one utility (hover:scale-x-[1.04] hover:scale-y-[.96]) that no longer has to repeat the lift.

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-21-group w-full min-h-svh flex flex-wrap">
<section class="tbh-21a flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh21-sans bg-tbh21a-stage" aria-label="Elastic lift button">
  <button type="button" class="cursor-pointer border-0 rounded-[14px] px-[42px] py-[18px] text-[17px] font-extrabold text-white bg-tbh21a-acc shadow-[0_8px_16px_-8px_color-mix(in_oklab,var(--color-tbh21a-acc)_70%,transparent)] transition-[translate,scale,box-shadow] duration-[450ms] ease-[cubic-bezier(.68,-.6,.32,1.6)] hover:-translate-y-1.5 hover:scale-x-[1.04] hover:scale-y-[.96] hover:shadow-[0_22px_30px_-12px_color-mix(in_oklab,var(--color-tbh21a-acc)_65%,transparent)] focus-visible:-translate-y-1.5 focus-visible:scale-x-[1.04] focus-visible:scale-y-[.96] active:-translate-y-px active:scale-[.97] active:duration-[120ms] focus-visible:outline-3 focus-visible:outline-tbh21a-acc focus-visible:outline-offset-4 motion-reduce:transition-[box-shadow] motion-reduce:duration-200 motion-reduce:hover:-translate-y-[3px] motion-reduce:hover:scale-100 motion-reduce:focus-visible:scale-100">
    Join the fun
  </button>
</section>
<section class="tbh-21b flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh21-sans bg-tbh21b-stage" aria-label="Wobble tilt button">
  <button type="button" class="cursor-pointer border-0 rounded-[14px] px-[42px] py-[18px] text-[17px] font-extrabold text-white bg-tbh21b-acc shadow-[0_10px_20px_-10px_var(--color-tbh21b-acc)] transition-[scale] duration-200 hover:animate-tbh21b-wob focus-visible:animate-tbh21b-wob active:scale-[.96] focus-visible:outline-3 focus-visible:outline-tbh21b-acc focus-visible:outline-offset-4 motion-reduce:hover:animate-none motion-reduce:focus-visible:animate-none motion-reduce:hover:scale-[1.03]">
    Say cheese
  </button>
</section>
</div>
@import "tailwindcss";

@theme {
  --color-tbh21a-acc: #ef8347;
  --color-tbh21a-acc: oklch(0.68 0.19 40);
  --color-tbh21a-stage: #fff5ec;
  --color-tbh21a-stage: oklch(0.97 0.02 60);
  --color-tbh21b-acc: #d966c4;
  --color-tbh21b-acc: oklch(0.66 0.18 320);
  --color-tbh21b-stage: #fbeffa;
  --color-tbh21b-stage: oklch(0.96 0.02 320);
  --font-tbh21-sans: 'Space Grotesk', system-ui, sans-serif;
  --animate-tbh21b-wob: tbh21b-wob 0.5s cubic-bezier(.36,.07,.19,.97);
}
/* Stays CSS: the one-shot wobble. It writes rotate and scale as discrete properties, so it
   composes with the button's own active:scale utility instead of overwriting it. */

@keyframes tbh21b-wob {
  0% {
    rotate: 0deg;
    scale: 1;
  }

  25% {
    rotate: -4deg;
    scale: 1.05;
  }

  50% {
    rotate: 3deg;
    scale: 1.03;
  }

  75% {
    rotate: -2deg;
    scale: 1.02;
  }

  100% {
    rotate: 0deg;
    scale: 1;
  }
}

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

.tbh-21a,
.tbh-21b {
  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-tbh21a-acc: #ef8347;
  --color-tbh21a-acc: oklch(0.68 0.19 40);
  --color-tbh21a-stage: #fff5ec;
  --color-tbh21a-stage: oklch(0.97 0.02 60);
  --color-tbh21b-acc: #d966c4;
  --color-tbh21b-acc: oklch(0.66 0.18 320);
  --color-tbh21b-stage: #fbeffa;
  --color-tbh21b-stage: oklch(0.96 0.02 320);
  --font-tbh21-sans: 'Space Grotesk', system-ui, sans-serif;
  --animate-tbh21b-wob: tbh21b-wob 0.5s cubic-bezier(.36,.07,.19,.97);
}
/* Stays CSS: the one-shot wobble. It writes rotate and scale as discrete properties, so it
   composes with the button's own active:scale utility instead of overwriting it. */

@keyframes tbh21b-wob {
  0% {
    rotate: 0deg;
    scale: 1;
  }

  25% {
    rotate: -4deg;
    scale: 1.05;
  }

  50% {
    rotate: 3deg;
    scale: 1.03;
  }

  75% {
    rotate: -2deg;
    scale: 1.02;
  }

  100% {
    rotate: 0deg;
    scale: 1;
  }
}

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

.tbh-21a,
.tbh-21b {
  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 squash survives edits now. translateY(-6px) scale(1.04,.96) was one value where changing the lift meant retyping the deformation; hover:-translate-y-1.5 hover:scale-x-[1.04] hover:scale-y-[.96] is three independent facts.
  • active:duration-[120ms] is the port's small revelation: a per-state duration override is a utility, where the CSS version needed a separate transition-duration declaration inside the :active rule.
  • UI change from the CSS original: both designs now spring on focus-visible:, and design A's reduced-motion fallback keeps a 3px lift with no squash rather than dropping to a shadow change alone.
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 Elastic Lift Spring Button Hover Effect
Source: https://codefronts.com/motion/tailwind-css-button-hover-effects/tailwind-elastic-lift-spring-button-hover-effect/

A bouncy, delightful CTA that springs up on hover &mdash; it lifts, squashes slightly and overshoots before settling. The squash is the part most implementations skip, and in v4 it is one utility (hover:scale-x-[1.04] hover:scale-y-[.96]) that no longer has to repeat the lift.
## HTML
```html
<div class="tbh-21-group w-full min-h-svh flex flex-wrap">
<section class="tbh-21a flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh21-sans bg-tbh21a-stage" aria-label="Elastic lift button">
  <button type="button" class="cursor-pointer border-0 rounded-[14px] px-[42px] py-[18px] text-[17px] font-extrabold text-white bg-tbh21a-acc shadow-[0_8px_16px_-8px_color-mix(in_oklab,var(--color-tbh21a-acc)_70%,transparent)] transition-[translate,scale,box-shadow] duration-[450ms] ease-[cubic-bezier(.68,-.6,.32,1.6)] hover:-translate-y-1.5 hover:scale-x-[1.04] hover:scale-y-[.96] hover:shadow-[0_22px_30px_-12px_color-mix(in_oklab,var(--color-tbh21a-acc)_65%,transparent)] focus-visible:-translate-y-1.5 focus-visible:scale-x-[1.04] focus-visible:scale-y-[.96] active:-translate-y-px active:scale-[.97] active:duration-[120ms] focus-visible:outline-3 focus-visible:outline-tbh21a-acc focus-visible:outline-offset-4 motion-reduce:transition-[box-shadow] motion-reduce:duration-200 motion-reduce:hover:-translate-y-[3px] motion-reduce:hover:scale-100 motion-reduce:focus-visible:scale-100">
    Join the fun
  </button>
</section>
<section class="tbh-21b flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh21-sans bg-tbh21b-stage" aria-label="Wobble tilt button">
  <button type="button" class="cursor-pointer border-0 rounded-[14px] px-[42px] py-[18px] text-[17px] font-extrabold text-white bg-tbh21b-acc shadow-[0_10px_20px_-10px_var(--color-tbh21b-acc)] transition-[scale] duration-200 hover:animate-tbh21b-wob focus-visible:animate-tbh21b-wob active:scale-[.96] focus-visible:outline-3 focus-visible:outline-tbh21b-acc focus-visible:outline-offset-4 motion-reduce:hover:animate-none motion-reduce:focus-visible:animate-none motion-reduce:hover:scale-[1.03]">
    Say cheese
  </button>
</section>
</div>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tbh21a-acc: #ef8347;
  --color-tbh21a-acc: oklch(0.68 0.19 40);
  --color-tbh21a-stage: #fff5ec;
  --color-tbh21a-stage: oklch(0.97 0.02 60);
  --color-tbh21b-acc: #d966c4;
  --color-tbh21b-acc: oklch(0.66 0.18 320);
  --color-tbh21b-stage: #fbeffa;
  --color-tbh21b-stage: oklch(0.96 0.02 320);
  --font-tbh21-sans: 'Space Grotesk', system-ui, sans-serif;
  --animate-tbh21b-wob: tbh21b-wob 0.5s cubic-bezier(.36,.07,.19,.97);
}
/* Stays CSS: the one-shot wobble. It writes rotate and scale as discrete properties, so it
   composes with the button's own active:scale utility instead of overwriting it. */

@keyframes tbh21b-wob {
  0% {
    rotate: 0deg;
    scale: 1;
  }

  25% {
    rotate: -4deg;
    scale: 1.05;
  }

  50% {
    rotate: 3deg;
    scale: 1.03;
  }

  75% {
    rotate: -2deg;
    scale: 1.02;
  }

  100% {
    rotate: 0deg;
    scale: 1;
  }
}

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

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

How this works

Squash and stretch, cheaply. Scaling X up 4% and Y down 4% while lifting reads as mass compressing against the lift — the oldest animation trick there is. In CSS it required writing translateY(-6px) scale(1.04,.96) as one value, and any later edit to the lift risked losing the squash. Here they are three utilities that cannot interfere.

The curve does the work. cubic-bezier(.68,-.6,.32,1.6) dips below the start value before travelling and overshoots past the target before settling. That is why 6px of movement feels like a spring rather than a slide.

Press overrides the spring. active:duration-[120ms] is the detail that makes this usable: without it, clicking mid-bounce feels laggy because the press has to fight a 450ms curve.

Make it yours

  • Bounce: the cubic-bezier. Raise the final control point past 1.6 for cartoonish, flatten to 1.0 for corporate.
  • Lift height: hover:-translate-y-1.5 (6px). Beyond ~10px the shadow has to grow a lot to stay believable.
  • Squash amount: the 1.04 / .96 pair — keep them inverse, or the button appears to change size rather than deform.
  • Design B's shake: the wobble keyframe's rotation stops (-4deg / 3deg / -2deg), a decaying sequence.

Gotchas — read before shipping

  • Keep the lift and scale modest: a button that grows 10% clips its own shadow and overlaps neighbours in a button row.
  • Grow the shadow WITH the lift (hover:shadow-[0_22px_30px_-12px_...]), or the button reads as scaled rather than raised.
  • Override the duration on active:. A springy curve on press feels broken.
  • Under motion-reduce: the lift is halved to a plain 3px translate with no squash and no spring — still a response, no bounce.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

cubic-bezier and transforms are universal; nothing here needs a fallback beyond Tailwind v4's own floor.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Plain CSSno Tailwind surface

Search CodeFronts

Loading…