36 Tailwind CSS Button Hover Effects
10 / 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 Modern 3D Skeuomorphic Button Press Effects

A soft tactile neumorphic CTA that appears extruded from the surface using paired light/dark shadows, depressing inward on press as the shadows invert. The port's contribution is legibility: four shadow stacks that used to live in four rules now sit next to each other, where you can actually see that they invert.

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-10-group w-full min-h-svh flex flex-wrap">
<section class="tbh-10a flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh10-sans bg-tbh10a-surf" aria-label="Skeuomorphic press button">
  <button type="button" class="cursor-pointer border-0 rounded-2xl px-10 py-[18px] text-base font-extrabold text-tbh10a-ink bg-tbh10a-surf shadow-[-6px_-6px_14px_color-mix(in_oklab,var(--color-tbh10a-surf)_60%,white),7px_7px_16px_color-mix(in_oklab,var(--color-tbh10a-surf)_62%,black)] transition-[translate,box-shadow,color] duration-[180ms] hover:text-tbh10a-acc hover:shadow-[-8px_-8px_18px_color-mix(in_oklab,var(--color-tbh10a-surf)_55%,white),9px_9px_20px_color-mix(in_oklab,var(--color-tbh10a-surf)_58%,black)] focus-visible:text-tbh10a-acc active:translate-y-0.5 active:shadow-[inset_-4px_-4px_10px_color-mix(in_oklab,var(--color-tbh10a-surf)_60%,white),inset_5px_5px_12px_color-mix(in_oklab,var(--color-tbh10a-surf)_62%,black)] focus-visible:outline-3 focus-visible:outline-tbh10a-acc focus-visible:outline-offset-4 motion-reduce:transition-[box-shadow,color] motion-reduce:duration-[120ms]">
    Save changes
  </button>
</section>
<section class="tbh-10b flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh10-sans bg-tbh10b-stage" aria-label="Glossy plastic button">
  <button type="button" class="relative overflow-hidden cursor-pointer border-0 rounded-[14px] px-[42px] py-[18px] text-base font-extrabold text-white bg-[linear-gradient(180deg,color-mix(in_oklab,var(--color-tbh10b-acc)_78%,white),var(--color-tbh10b-acc))] [text-shadow:0_1px_1px_oklch(0_0_0/0.25)] shadow-[inset_0_1px_0_oklch(1_0_0/0.7),inset_0_-6px_12px_-6px_oklch(0_0_0/0.4),0_10px_20px_-8px_color-mix(in_oklab,var(--color-tbh10b-acc)_60%,transparent)] transition-[translate,box-shadow] duration-[140ms] before:content-[''] before:absolute before:top-0.5 before:left-2 before:right-2 before:h-[42%] before:pointer-events-none before:[border-radius:12px_12px_40%_40%/12px_12px_60%_60%] before:bg-[linear-gradient(180deg,oklch(1_0_0/0.55),transparent)] hover:-translate-y-px focus-visible:-translate-y-px active:translate-y-0.5 active:shadow-[inset_0_1px_0_oklch(1_0_0/0.5),inset_0_4px_10px_-4px_oklch(0_0_0/0.5),0_4px_10px_-6px_color-mix(in_oklab,var(--color-tbh10b-acc)_60%,transparent)] focus-visible:outline-3 focus-visible:outline-tbh10b-acc focus-visible:outline-offset-4 motion-reduce:transition-[box-shadow] motion-reduce:duration-100 motion-reduce:hover:translate-y-0">
    Confirm order
  </button>
</section>
</div>
@import "tailwindcss";

@theme {
  --color-tbh10a-surf: #e6e9ef;
  --color-tbh10a-surf: oklch(0.92 0.008 265);
  --color-tbh10a-ink: #6b7280;
  --color-tbh10a-ink: oklch(0.5 0.02 265);
  --color-tbh10a-acc: #5b7cdb;
  --color-tbh10a-acc: oklch(0.55 0.16 265);
  --color-tbh10b-acc: #4d7ce0;
  --color-tbh10b-acc: oklch(0.6 0.18 250);
  --color-tbh10b-stage: #e8ecf3;
  --color-tbh10b-stage: oklch(0.93 0.01 255);
  --font-tbh10-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Nothing stays CSS: every shadow stack, gradient and text-shadow is an arbitrary value. */

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

.tbh-10a,
.tbh-10b {
  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-tbh10a-surf: #e6e9ef;
  --color-tbh10a-surf: oklch(0.92 0.008 265);
  --color-tbh10a-ink: #6b7280;
  --color-tbh10a-ink: oklch(0.5 0.02 265);
  --color-tbh10a-acc: #5b7cdb;
  --color-tbh10a-acc: oklch(0.55 0.16 265);
  --color-tbh10b-acc: #4d7ce0;
  --color-tbh10b-acc: oklch(0.6 0.18 250);
  --color-tbh10b-stage: #e8ecf3;
  --color-tbh10b-stage: oklch(0.93 0.01 255);
  --font-tbh10-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Nothing stays CSS: every shadow stack, gradient and text-shadow is an arbitrary value. */

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

.tbh-10a,
.tbh-10b {
  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.

  • Four shadow stacks in four rules become four stacks in one class list, and the inversion is finally visible as an inversion — this is the demo where the port's benefit is purely about reading the code, since not one value changed.
  • color-mix() inside an arbitrary shadow value works exactly as it does in CSS, so the derived-from-one-token architecture survives the port intact. Deriving the shadows is what keeps neumorphism's shared-colour rule from being a comment nobody reads.
  • UI change from the CSS original: both designs now mirror the hover state on focus-visible: (design A's accent label, design B's 1px lift), which on a borderless surface is the difference between a visible and an invisible focus.
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 Modern 3D Skeuomorphic Button Press Effects
Source: https://codefronts.com/motion/tailwind-css-button-hover-effects/tailwind-modern-3d-skeuomorphic-button-press-effects/

A soft tactile neumorphic CTA that appears extruded from the surface using paired light/dark shadows, depressing inward on press as the shadows invert. The port's contribution is legibility: four shadow stacks that used to live in four rules now sit next to each other, where you can actually see that they invert.
## HTML
```html
<div class="tbh-10-group w-full min-h-svh flex flex-wrap">
<section class="tbh-10a flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh10-sans bg-tbh10a-surf" aria-label="Skeuomorphic press button">
  <button type="button" class="cursor-pointer border-0 rounded-2xl px-10 py-[18px] text-base font-extrabold text-tbh10a-ink bg-tbh10a-surf shadow-[-6px_-6px_14px_color-mix(in_oklab,var(--color-tbh10a-surf)_60%,white),7px_7px_16px_color-mix(in_oklab,var(--color-tbh10a-surf)_62%,black)] transition-[translate,box-shadow,color] duration-[180ms] hover:text-tbh10a-acc hover:shadow-[-8px_-8px_18px_color-mix(in_oklab,var(--color-tbh10a-surf)_55%,white),9px_9px_20px_color-mix(in_oklab,var(--color-tbh10a-surf)_58%,black)] focus-visible:text-tbh10a-acc active:translate-y-0.5 active:shadow-[inset_-4px_-4px_10px_color-mix(in_oklab,var(--color-tbh10a-surf)_60%,white),inset_5px_5px_12px_color-mix(in_oklab,var(--color-tbh10a-surf)_62%,black)] focus-visible:outline-3 focus-visible:outline-tbh10a-acc focus-visible:outline-offset-4 motion-reduce:transition-[box-shadow,color] motion-reduce:duration-[120ms]">
    Save changes
  </button>
</section>
<section class="tbh-10b flex-[1_1_340px] min-w-[300px] grid place-items-center px-6 py-14 font-tbh10-sans bg-tbh10b-stage" aria-label="Glossy plastic button">
  <button type="button" class="relative overflow-hidden cursor-pointer border-0 rounded-[14px] px-[42px] py-[18px] text-base font-extrabold text-white bg-[linear-gradient(180deg,color-mix(in_oklab,var(--color-tbh10b-acc)_78%,white),var(--color-tbh10b-acc))] [text-shadow:0_1px_1px_oklch(0_0_0/0.25)] shadow-[inset_0_1px_0_oklch(1_0_0/0.7),inset_0_-6px_12px_-6px_oklch(0_0_0/0.4),0_10px_20px_-8px_color-mix(in_oklab,var(--color-tbh10b-acc)_60%,transparent)] transition-[translate,box-shadow] duration-[140ms] before:content-[''] before:absolute before:top-0.5 before:left-2 before:right-2 before:h-[42%] before:pointer-events-none before:[border-radius:12px_12px_40%_40%/12px_12px_60%_60%] before:bg-[linear-gradient(180deg,oklch(1_0_0/0.55),transparent)] hover:-translate-y-px focus-visible:-translate-y-px active:translate-y-0.5 active:shadow-[inset_0_1px_0_oklch(1_0_0/0.5),inset_0_4px_10px_-4px_oklch(0_0_0/0.5),0_4px_10px_-6px_color-mix(in_oklab,var(--color-tbh10b-acc)_60%,transparent)] focus-visible:outline-3 focus-visible:outline-tbh10b-acc focus-visible:outline-offset-4 motion-reduce:transition-[box-shadow] motion-reduce:duration-100 motion-reduce:hover:translate-y-0">
    Confirm order
  </button>
</section>
</div>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tbh10a-surf: #e6e9ef;
  --color-tbh10a-surf: oklch(0.92 0.008 265);
  --color-tbh10a-ink: #6b7280;
  --color-tbh10a-ink: oklch(0.5 0.02 265);
  --color-tbh10a-acc: #5b7cdb;
  --color-tbh10a-acc: oklch(0.55 0.16 265);
  --color-tbh10b-acc: #4d7ce0;
  --color-tbh10b-acc: oklch(0.6 0.18 250);
  --color-tbh10b-stage: #e8ecf3;
  --color-tbh10b-stage: oklch(0.93 0.01 255);
  --font-tbh10-sans: 'Space Grotesk', system-ui, sans-serif;
}
/* Nothing stays CSS: every shadow stack, gradient and text-shadow is an arbitrary value. */

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

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

How this works

Neumorphism is two shadows and a shared colour. The button and its stage must be the same base colour — the shape exists only as light. Deriving both shadows from one @theme token with color-mix() means that constraint is enforced by the code rather than by discipline.

The press inverts, it does not move much. active:translate-y-0.5 plus inset shadows: 2px of travel and a complete lighting flip. The flip is what sells it, which is why the resting and active stacks are worth reading side by side.

Design B is the glossy-plastic cousin. A vertical gradient fill, an inset rim highlight, a text-shadow for moulded type, and a before: gloss cap with an eight-value radius. Same physics, different decade.

Make it yours

  • Surface: --color-tbh10a-surf. Both shadows and the stage read it, so one change rethemes the demo.
  • Softness: the blur radii (14px / 16px). Larger is softer and flatter; smaller is crisper and more plastic.
  • Press depth: active:translate-y-0.5 and the inset offsets — they should change together.
  • Accent: design A shifts the label to hover:text-tbh10a-acc, the only colour in an otherwise monochrome surface.

Gotchas — read before shipping

  • Button and stage MUST share the base colour. A different background breaks the illusion instantly, which is the whole reason the surface is a token.
  • Neumorphism has no visible border, so a focus ring is non-negotiable: both designs keep focus-visible:outline-3 ... outline-offset-4 in an accent colour.
  • Label contrast is the standing risk on a low-contrast surface — design A's ink is oklch(0.5 ...) on a 0.92 surface, which clears 4.5:1. Lighten either and re-check.
  • Design B's gloss cap needs pointer-events-none; it covers the top 42% of the button and would otherwise eat clicks.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

Layered and inset box-shadow are universal; color-mix() is Tailwind v4's own floor, so no additional gate.

Techniques used in this demo

Search CodeFronts

Loading…