02 / 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 Background Slide Hover Button (Four Directions)
Four directional fills that sweep across the button face — left, right, top, bottom. The port collapses eight CSS rules (four resting transforms, four hover transforms) into four class lists, each stating its own direction: before:-translate-x-full hover:before:translate-x-0.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tab-02 w-full min-h-svh grid place-items-center bg-tab02-bg font-tab02-sans px-6 py-10">
<div class="flex flex-col items-center gap-8">
<p class="text-[0.8rem] font-semibold tracking-[0.12em] uppercase text-tab02-fill/70 m-0">Background Slide Directions</p>
<div class="grid grid-cols-2 gap-4">
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:-translate-x-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-x-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-x-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Left</span></button>
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:translate-x-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-x-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-x-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Right</span></button>
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:-translate-y-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-y-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Top</span></button>
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:translate-y-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-y-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Bottom</span></button>
</div>
</div>
</section><section class="tab-02 w-full min-h-svh grid place-items-center bg-tab02-bg font-tab02-sans px-6 py-10">
<div class="flex flex-col items-center gap-8">
<p class="text-[0.8rem] font-semibold tracking-[0.12em] uppercase text-tab02-fill/70 m-0">Background Slide Directions</p>
<div class="grid grid-cols-2 gap-4">
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:-translate-x-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-x-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-x-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Left</span></button>
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:translate-x-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-x-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-x-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Right</span></button>
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:-translate-y-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-y-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Top</span></button>
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:translate-y-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-y-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Bottom</span></button>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-tab02-bg: #f0eeff;
--color-tab02-bg: oklch(0.95 0.02 282);
--color-tab02-fill: #6c63ff;
--color-tab02-fill: oklch(0.56 0.21 282);
--font-tab02-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tab-02 {
width: 100%;
min-height: 100svh;
}
.tab-02 ::selection {
background: var(--color-tab02-fill);
color: #fff;
}@import "tailwindcss";
@theme {
--color-tab02-bg: #f0eeff;
--color-tab02-bg: oklch(0.95 0.02 282);
--color-tab02-fill: #6c63ff;
--color-tab02-fill: oklch(0.56 0.21 282);
--font-tab02-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tab-02 {
width: 100%;
min-height: 100svh;
}
.tab-02 ::selection {
background: var(--color-tab02-fill);
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-tab02-bg: #f0eeff;
--color-tab02-bg: oklch(0.95 0.02 282);
--color-tab02-fill: #6c63ff;
--color-tab02-fill: oklch(0.56 0.21 282);
--font-tab02-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tab-02 {
width: 100%;
min-height: 100svh;
}
.tab-02 ::selection {
background: var(--color-tab02-fill);
color: #fff;
}@import "tailwindcss";
@theme {
--color-tab02-bg: #f0eeff;
--color-tab02-bg: oklch(0.95 0.02 282);
--color-tab02-fill: #6c63ff;
--color-tab02-fill: oklch(0.56 0.21 282);
--font-tab02-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tab-02 {
width: 100%;
min-height: 100svh;
}
.tab-02 ::selection {
background: var(--color-tab02-fill);
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.
- Eight CSS rules become four class lists. The repetition moved from the stylesheet into the markup, which is the trade every directional-variant port makes — and here it is worth it, because direction is now stated where the button is.
before:content-['']is mandatory in Tailwind: a pseudo-element with nocontentdoes not render, and the utility set does not imply it.- UI change from the CSS original: every hover state gained a
focus-visibletwin and the buttons gained 44px minimum height.
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 Background Slide Hover Button (Four Directions)
Source: https://codefronts.com/motion/tailwind-css-animated-buttons/tailwind-background-slide-hover-button/
Four directional fills that sweep across the button face — left, right, top, bottom. The port collapses eight CSS rules (four resting transforms, four hover transforms) into four class lists, each stating its own direction: before:-translate-x-full hover:before:translate-x-0.
## HTML
```html
<section class="tab-02 w-full min-h-svh grid place-items-center bg-tab02-bg font-tab02-sans px-6 py-10">
<div class="flex flex-col items-center gap-8">
<p class="text-[0.8rem] font-semibold tracking-[0.12em] uppercase text-tab02-fill/70 m-0">Background Slide Directions</p>
<div class="grid grid-cols-2 gap-4">
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:-translate-x-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-x-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-x-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Left</span></button>
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:translate-x-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-x-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-x-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Right</span></button>
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:-translate-y-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-y-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Top</span></button>
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:translate-y-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-y-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Bottom</span></button>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tab02-bg: #f0eeff;
--color-tab02-bg: oklch(0.95 0.02 282);
--color-tab02-fill: #6c63ff;
--color-tab02-fill: oklch(0.56 0.21 282);
--font-tab02-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tab-02 {
width: 100%;
min-height: 100svh;
}
.tab-02 ::selection {
background: var(--color-tab02-fill);
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 Background Slide Hover Button (Four Directions)
Source: https://codefronts.com/motion/tailwind-css-animated-buttons/tailwind-background-slide-hover-button/
Four directional fills that sweep across the button face — left, right, top, bottom. The port collapses eight CSS rules (four resting transforms, four hover transforms) into four class lists, each stating its own direction: before:-translate-x-full hover:before:translate-x-0.
## HTML
```html
<section class="tab-02 w-full min-h-svh grid place-items-center bg-tab02-bg font-tab02-sans px-6 py-10">
<div class="flex flex-col items-center gap-8">
<p class="text-[0.8rem] font-semibold tracking-[0.12em] uppercase text-tab02-fill/70 m-0">Background Slide Directions</p>
<div class="grid grid-cols-2 gap-4">
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:-translate-x-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-x-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-x-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Left</span></button>
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:translate-x-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-x-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-x-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Right</span></button>
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:-translate-y-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-y-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Top</span></button>
<button type="button" class="relative overflow-hidden min-h-11 px-8 text-[0.95rem] font-bold tracking-[0.03em] text-tab02-fill bg-transparent border-2 border-tab02-fill rounded-lg cursor-pointer transition-colors duration-[350ms] before:content-[''] before:absolute before:inset-0 before:bg-tab02-fill before:translate-y-full before:transition-transform before:duration-[350ms] before:ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-white hover:before:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tab02-fill focus-visible:text-white focus-visible:before:translate-y-0 active:scale-[0.97] motion-reduce:before:transition-none motion-reduce:transition-none"><span class="relative z-10">Slide Bottom</span></button>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tab02-bg: #f0eeff;
--color-tab02-bg: oklch(0.95 0.02 282);
--color-tab02-fill: #6c63ff;
--color-tab02-fill: oklch(0.56 0.21 282);
--font-tab02-sans: 'Space Grotesk', system-ui, sans-serif;
}
.tab-02 {
width: 100%;
min-height: 100svh;
}
.tab-02 ::selection {
background: var(--color-tab02-fill);
color: #fff;
}
```How this works
The direction is now a word in the class list. The CSS version needed a modifier class per direction plus a paired hover rule — eight selectors to express four behaviours. Tailwind states the resting transform and the hover transform on the same element:
before:-translate-x-full hover:before:translate-x-0so "slides in from the left" is legible without cross-referencing a stylesheet. Only transform animates, so the compositor does all the work.
The fill inherits the token. before:bg-tab02-fill and border-tab02-fill read one @theme colour, so the resting outline and the incoming fill can never drift apart.
Focus is a first-class state. Each button pairs every hover:before: with a focus-visible:before:, so a keyboard user sees the same sweep a mouse user does — a genuine upgrade over the hover-only original.
Make it yours
- Gradient fill: swap
before:bg-tab02-fillforbefore:bg-[linear-gradient(135deg,#6c63ff,#c471ed)]. - Speed:
before:duration-[350ms]→before:duration-200for a snappier sweep. - Diagonal sweep: combine two axes —
before:-translate-x-full before:-translate-y-full hover:before:translate-x-0 hover:before:translate-y-0.
Gotchas — read before shipping
overflow-hiddenclipsshadow-*as well as the fill. If you need both, move the shadow to a wrapper.- The label needs
relative z-10. Without it the fill paints over the text and the button appears to go blank on hover. - Keep
before:inset-0rather than a percentage width — percentage sizing on an absolutely-positioned pseudo-element inside flex or grid can resolve against the wrong box.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Pseudo-element transforms are universally supported; the floor is Tailwind v4's generated sheet.