28 / 30
All 30 in 30 Tailwind CSS Hover Effects
- 01Tailwind Underline Draw Hover Effect
- 02Tailwind Text Glitch Hover Effect
- 03Tailwind Letter Spacing Expand Hover Effect
- 04Tailwind Gradient Text Reveal Hover Effect
- 05Tailwind Split Text Hover Effect
- 06Tailwind Neon Glow Text Hover Effect
- 07Tailwind Magnetic Liquid Button Hover Effect
- 08Tailwind Border Draw Hover Effect
- 09Tailwind Shimmer Shine Button Hover Effect
- 10Tailwind Fill Wipe Button Hover Effect
- 11Tailwind 3D Press Button Hover Effect
- 12Tailwind Ripple Button Hover Effect
- 13Tailwind 3D Tilt Card Hover Effect
- 14Tailwind Card Flip Hover Effect
- 15Tailwind Glassmorphism Card Hover Effect
- 16Tailwind Spotlight Card Hover Effect
- 17Tailwind Slide Reveal Card Hover Effect
- 18Tailwind Stack Lift Card Hover Effect
- 19Tailwind Zoom Pan Image Hover Effect
- 20Tailwind Color Channel Split Hover Effect
- 21Tailwind Duotone Image Hover Effect
- 22Tailwind Curtain Reveal Image Hover Effect
- 23Tailwind Ken Burns Image Hover Effect
- 24Tailwind Image Tilt Depth Hover Effect
- 25Tailwind Underline Slide Nav Hover Effect
- 26Tailwind Highlight Fill Nav Hover Effect
- 27Tailwind Strikethrough Hover Link Effect
- 28Tailwind Inline Word Swap Hover Effect
- 29Tailwind Dot Trail Cursor Hover Effect
- 30Tailwind Magnetic Cursor Pull Hover Effect
Tailwind Inline Word Swap Hover Effect
Six ways to replace a word on hover — slide up, clip reveal, cross-fade, scale-in, blur swap and a flip-down. Two absolutely stacked spans, one leaving and one arriving, with the incoming word marked aria-hidden.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="thv-28 w-full min-h-svh bg-thv28-bg font-thv28-sans px-8 py-12 flex flex-col items-start gap-8 max-w-[640px] mx-auto">
<p class="self-center text-[0.72rem] tracking-[0.15em] uppercase text-thv28-dim">Inline Word Swap — 6 Styles</p>
<div class="flex items-center gap-6">
<a href="#" aria-label="Design Systems" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-transform duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:-translate-y-full group-focus-visible:-translate-y-full motion-reduce:transition-none">Design</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc translate-y-full transition-transform duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:translate-y-0 group-focus-visible:translate-y-0 motion-reduce:transition-none">Systems</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Slide Up</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Make it Work" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink [clip-path:inset(0_0_0_0)] transition-[clip-path] duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:[clip-path:inset(0_0_0_100%)] group-focus-visible:[clip-path:inset(0_0_0_100%)] motion-reduce:transition-none">Make it</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc [clip-path:inset(0_100%_0_0)] transition-[clip-path] duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none">Work</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Clip Reveal</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Start Now" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-opacity duration-250 group-hover:opacity-0 group-focus-visible:opacity-0">Start</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc opacity-0 transition-opacity duration-250 delay-100 group-hover:opacity-100 group-focus-visible:opacity-100">Now</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Fade Cross</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Build Fast" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-[opacity,transform] duration-250 group-hover:opacity-0 group-hover:scale-125 group-focus-visible:opacity-0 motion-reduce:transition-opacity">Build</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc opacity-0 scale-[.6] transition-[opacity,transform] duration-300 delay-[50ms] ease-[cubic-bezier(.34,1.56,.64,1)] group-hover:opacity-100 group-hover:scale-100 group-focus-visible:opacity-100 group-focus-visible:scale-100 motion-reduce:transition-opacity">Fast</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Scale In</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Ship it" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-[filter,opacity] duration-300 group-hover:blur-[8px] group-hover:opacity-0 group-focus-visible:opacity-0">Ship</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc blur-[8px] opacity-0 transition-[filter,opacity] duration-300 delay-[50ms] group-hover:blur-0 group-hover:opacity-100 group-focus-visible:blur-0 group-focus-visible:opacity-100">it</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Blur Swap</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Create Iterate" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] perspective-[300px] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink origin-bottom transition-[transform,opacity] duration-350 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-x-90 group-hover:opacity-0 group-focus-visible:rotate-x-90 group-focus-visible:opacity-0 motion-reduce:transition-opacity">Create</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc origin-top rotate-x-[-90deg] opacity-0 transition-[transform,opacity] duration-350 delay-[50ms] ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-x-0 group-hover:opacity-100 group-focus-visible:rotate-x-0 group-focus-visible:opacity-100 motion-reduce:transition-opacity">Iterate</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Flip Down</span>
</div>
</section><section class="thv-28 w-full min-h-svh bg-thv28-bg font-thv28-sans px-8 py-12 flex flex-col items-start gap-8 max-w-[640px] mx-auto">
<p class="self-center text-[0.72rem] tracking-[0.15em] uppercase text-thv28-dim">Inline Word Swap — 6 Styles</p>
<div class="flex items-center gap-6">
<a href="#" aria-label="Design Systems" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-transform duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:-translate-y-full group-focus-visible:-translate-y-full motion-reduce:transition-none">Design</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc translate-y-full transition-transform duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:translate-y-0 group-focus-visible:translate-y-0 motion-reduce:transition-none">Systems</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Slide Up</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Make it Work" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink [clip-path:inset(0_0_0_0)] transition-[clip-path] duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:[clip-path:inset(0_0_0_100%)] group-focus-visible:[clip-path:inset(0_0_0_100%)] motion-reduce:transition-none">Make it</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc [clip-path:inset(0_100%_0_0)] transition-[clip-path] duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none">Work</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Clip Reveal</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Start Now" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-opacity duration-250 group-hover:opacity-0 group-focus-visible:opacity-0">Start</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc opacity-0 transition-opacity duration-250 delay-100 group-hover:opacity-100 group-focus-visible:opacity-100">Now</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Fade Cross</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Build Fast" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-[opacity,transform] duration-250 group-hover:opacity-0 group-hover:scale-125 group-focus-visible:opacity-0 motion-reduce:transition-opacity">Build</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc opacity-0 scale-[.6] transition-[opacity,transform] duration-300 delay-[50ms] ease-[cubic-bezier(.34,1.56,.64,1)] group-hover:opacity-100 group-hover:scale-100 group-focus-visible:opacity-100 group-focus-visible:scale-100 motion-reduce:transition-opacity">Fast</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Scale In</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Ship it" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-[filter,opacity] duration-300 group-hover:blur-[8px] group-hover:opacity-0 group-focus-visible:opacity-0">Ship</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc blur-[8px] opacity-0 transition-[filter,opacity] duration-300 delay-[50ms] group-hover:blur-0 group-hover:opacity-100 group-focus-visible:blur-0 group-focus-visible:opacity-100">it</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Blur Swap</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Create Iterate" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] perspective-[300px] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink origin-bottom transition-[transform,opacity] duration-350 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-x-90 group-hover:opacity-0 group-focus-visible:rotate-x-90 group-focus-visible:opacity-0 motion-reduce:transition-opacity">Create</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc origin-top rotate-x-[-90deg] opacity-0 transition-[transform,opacity] duration-350 delay-[50ms] ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-x-0 group-hover:opacity-100 group-focus-visible:rotate-x-0 group-focus-visible:opacity-100 motion-reduce:transition-opacity">Iterate</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Flip Down</span>
</div>
</section>@import "tailwindcss";
@theme {
--color-thv28-bg: #0b0b0e;
--color-thv28-bg: oklch(0.12 0.01 285);
--color-thv28-ink: #d5d5da;
--color-thv28-ink: oklch(0.86 0.01 285);
--color-thv28-dim: #8a8a96;
--color-thv28-dim: oklch(0.64 0.01 285);
--color-thv28-acc: #7c6af7;
--color-thv28-acc: oklch(0.62 0.2 285);
--font-thv28-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-28 {
width: 100%;
min-height: 100svh;
}
.thv-28 ::selection {
background: var(--color-thv28-acc);
color: #fff;
}@import "tailwindcss";
@theme {
--color-thv28-bg: #0b0b0e;
--color-thv28-bg: oklch(0.12 0.01 285);
--color-thv28-ink: #d5d5da;
--color-thv28-ink: oklch(0.86 0.01 285);
--color-thv28-dim: #8a8a96;
--color-thv28-dim: oklch(0.64 0.01 285);
--color-thv28-acc: #7c6af7;
--color-thv28-acc: oklch(0.62 0.2 285);
--font-thv28-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-28 {
width: 100%;
min-height: 100svh;
}
.thv-28 ::selection {
background: var(--color-thv28-acc);
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-thv28-bg: #0b0b0e;
--color-thv28-bg: oklch(0.12 0.01 285);
--color-thv28-ink: #d5d5da;
--color-thv28-ink: oklch(0.86 0.01 285);
--color-thv28-dim: #8a8a96;
--color-thv28-dim: oklch(0.64 0.01 285);
--color-thv28-acc: #7c6af7;
--color-thv28-acc: oklch(0.62 0.2 285);
--font-thv28-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-28 {
width: 100%;
min-height: 100svh;
}
.thv-28 ::selection {
background: var(--color-thv28-acc);
color: #fff;
}@import "tailwindcss";
@theme {
--color-thv28-bg: #0b0b0e;
--color-thv28-bg: oklch(0.12 0.01 285);
--color-thv28-ink: #d5d5da;
--color-thv28-ink: oklch(0.86 0.01 285);
--color-thv28-dim: #8a8a96;
--color-thv28-dim: oklch(0.64 0.01 285);
--color-thv28-acc: #7c6af7;
--color-thv28-acc: oklch(0.62 0.2 285);
--font-thv28-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-28 {
width: 100%;
min-height: 100svh;
}
.thv-28 ::selection {
background: var(--color-thv28-acc);
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&family=JetBrains+Mono:wght@400;500;600;800&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&family=JetBrains+Mono:wght@400;500;600;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Outgoing and incoming states are two sibling class lists you can read side by side, which is the cheapest way to keep a swap symmetrical.
- UI change from the CSS original: every pair swaps on
group-focus-visible:too, and the source'saria-label="Ship Ship"(which swapped a word for itself) is fixed to a real pair. - Under
motion-reduce:the transforms are dropped but the cross-fade remains, so the second word still arrives.
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 Inline Word Swap Hover Effect
Source: https://codefronts.com/motion/tailwind-css-hover-effects/tailwind-inline-word-swap-hover-effect/
Six ways to replace a word on hover — slide up, clip reveal, cross-fade, scale-in, blur swap and a flip-down. Two absolutely stacked spans, one leaving and one arriving, with the incoming word marked aria-hidden.
## HTML
```html
<section class="thv-28 w-full min-h-svh bg-thv28-bg font-thv28-sans px-8 py-12 flex flex-col items-start gap-8 max-w-[640px] mx-auto">
<p class="self-center text-[0.72rem] tracking-[0.15em] uppercase text-thv28-dim">Inline Word Swap — 6 Styles</p>
<div class="flex items-center gap-6">
<a href="#" aria-label="Design Systems" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-transform duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:-translate-y-full group-focus-visible:-translate-y-full motion-reduce:transition-none">Design</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc translate-y-full transition-transform duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:translate-y-0 group-focus-visible:translate-y-0 motion-reduce:transition-none">Systems</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Slide Up</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Make it Work" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink [clip-path:inset(0_0_0_0)] transition-[clip-path] duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:[clip-path:inset(0_0_0_100%)] group-focus-visible:[clip-path:inset(0_0_0_100%)] motion-reduce:transition-none">Make it</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc [clip-path:inset(0_100%_0_0)] transition-[clip-path] duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none">Work</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Clip Reveal</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Start Now" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-opacity duration-250 group-hover:opacity-0 group-focus-visible:opacity-0">Start</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc opacity-0 transition-opacity duration-250 delay-100 group-hover:opacity-100 group-focus-visible:opacity-100">Now</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Fade Cross</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Build Fast" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-[opacity,transform] duration-250 group-hover:opacity-0 group-hover:scale-125 group-focus-visible:opacity-0 motion-reduce:transition-opacity">Build</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc opacity-0 scale-[.6] transition-[opacity,transform] duration-300 delay-[50ms] ease-[cubic-bezier(.34,1.56,.64,1)] group-hover:opacity-100 group-hover:scale-100 group-focus-visible:opacity-100 group-focus-visible:scale-100 motion-reduce:transition-opacity">Fast</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Scale In</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Ship it" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-[filter,opacity] duration-300 group-hover:blur-[8px] group-hover:opacity-0 group-focus-visible:opacity-0">Ship</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc blur-[8px] opacity-0 transition-[filter,opacity] duration-300 delay-[50ms] group-hover:blur-0 group-hover:opacity-100 group-focus-visible:blur-0 group-focus-visible:opacity-100">it</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Blur Swap</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Create Iterate" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] perspective-[300px] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink origin-bottom transition-[transform,opacity] duration-350 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-x-90 group-hover:opacity-0 group-focus-visible:rotate-x-90 group-focus-visible:opacity-0 motion-reduce:transition-opacity">Create</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc origin-top rotate-x-[-90deg] opacity-0 transition-[transform,opacity] duration-350 delay-[50ms] ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-x-0 group-hover:opacity-100 group-focus-visible:rotate-x-0 group-focus-visible:opacity-100 motion-reduce:transition-opacity">Iterate</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Flip Down</span>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-thv28-bg: #0b0b0e;
--color-thv28-bg: oklch(0.12 0.01 285);
--color-thv28-ink: #d5d5da;
--color-thv28-ink: oklch(0.86 0.01 285);
--color-thv28-dim: #8a8a96;
--color-thv28-dim: oklch(0.64 0.01 285);
--color-thv28-acc: #7c6af7;
--color-thv28-acc: oklch(0.62 0.2 285);
--font-thv28-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-28 {
width: 100%;
min-height: 100svh;
}
.thv-28 ::selection {
background: var(--color-thv28-acc);
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 Inline Word Swap Hover Effect
Source: https://codefronts.com/motion/tailwind-css-hover-effects/tailwind-inline-word-swap-hover-effect/
Six ways to replace a word on hover — slide up, clip reveal, cross-fade, scale-in, blur swap and a flip-down. Two absolutely stacked spans, one leaving and one arriving, with the incoming word marked aria-hidden.
## HTML
```html
<section class="thv-28 w-full min-h-svh bg-thv28-bg font-thv28-sans px-8 py-12 flex flex-col items-start gap-8 max-w-[640px] mx-auto">
<p class="self-center text-[0.72rem] tracking-[0.15em] uppercase text-thv28-dim">Inline Word Swap — 6 Styles</p>
<div class="flex items-center gap-6">
<a href="#" aria-label="Design Systems" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-transform duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:-translate-y-full group-focus-visible:-translate-y-full motion-reduce:transition-none">Design</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc translate-y-full transition-transform duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:translate-y-0 group-focus-visible:translate-y-0 motion-reduce:transition-none">Systems</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Slide Up</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Make it Work" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink [clip-path:inset(0_0_0_0)] transition-[clip-path] duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:[clip-path:inset(0_0_0_100%)] group-focus-visible:[clip-path:inset(0_0_0_100%)] motion-reduce:transition-none">Make it</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc [clip-path:inset(0_100%_0_0)] transition-[clip-path] duration-300 ease-[cubic-bezier(.4,0,.2,1)] group-hover:[clip-path:inset(0_0_0_0)] group-focus-visible:[clip-path:inset(0_0_0_0)] motion-reduce:transition-none">Work</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Clip Reveal</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Start Now" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-opacity duration-250 group-hover:opacity-0 group-focus-visible:opacity-0">Start</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc opacity-0 transition-opacity duration-250 delay-100 group-hover:opacity-100 group-focus-visible:opacity-100">Now</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Fade Cross</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Build Fast" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-[opacity,transform] duration-250 group-hover:opacity-0 group-hover:scale-125 group-focus-visible:opacity-0 motion-reduce:transition-opacity">Build</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc opacity-0 scale-[.6] transition-[opacity,transform] duration-300 delay-[50ms] ease-[cubic-bezier(.34,1.56,.64,1)] group-hover:opacity-100 group-hover:scale-100 group-focus-visible:opacity-100 group-focus-visible:scale-100 motion-reduce:transition-opacity">Fast</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Scale In</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Ship it" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink transition-[filter,opacity] duration-300 group-hover:blur-[8px] group-hover:opacity-0 group-focus-visible:opacity-0">Ship</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc blur-[8px] opacity-0 transition-[filter,opacity] duration-300 delay-[50ms] group-hover:blur-0 group-hover:opacity-100 group-focus-visible:blur-0 group-focus-visible:opacity-100">it</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Blur Swap</span>
</div>
<div class="flex items-center gap-6">
<a href="#" aria-label="Create Iterate" class="group relative inline-block overflow-hidden min-w-[8ch] h-[1.2em] perspective-[300px] text-[1.6rem] font-bold leading-[1.2] no-underline align-bottom rounded-xs focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-thv28-acc">
<span class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-ink origin-bottom transition-[transform,opacity] duration-350 ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-x-90 group-hover:opacity-0 group-focus-visible:rotate-x-90 group-focus-visible:opacity-0 motion-reduce:transition-opacity">Create</span>
<span aria-hidden="true" class="absolute inset-x-0 top-0 block whitespace-nowrap text-thv28-acc origin-top rotate-x-[-90deg] opacity-0 transition-[transform,opacity] duration-350 delay-[50ms] ease-[cubic-bezier(.4,0,.2,1)] group-hover:rotate-x-0 group-hover:opacity-100 group-focus-visible:rotate-x-0 group-focus-visible:opacity-100 motion-reduce:transition-opacity">Iterate</span>
</a>
<span class="min-w-[90px] text-[0.68rem] tracking-[0.1em] uppercase text-thv28-dim">Flip Down</span>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-thv28-bg: #0b0b0e;
--color-thv28-bg: oklch(0.12 0.01 285);
--color-thv28-ink: #d5d5da;
--color-thv28-ink: oklch(0.86 0.01 285);
--color-thv28-dim: #8a8a96;
--color-thv28-dim: oklch(0.64 0.01 285);
--color-thv28-acc: #7c6af7;
--color-thv28-acc: oklch(0.62 0.2 285);
--font-thv28-sans: 'Space Grotesk', system-ui, sans-serif;
}
.thv-28 {
width: 100%;
min-height: 100svh;
}
.thv-28 ::selection {
background: var(--color-thv28-acc);
color: #fff;
}
```How this works
Two spans, one box. The link is relative inline-block overflow-hidden with a fixed h-[1.2em] and a min-w-[8ch]; both words are absolute inset-x-0 top-0, so no layout shift can happen between a short word and a long one.
Six exits, six entrances. Each variant pairs an outgoing transform with its complement — up/up, clip-right/clip-left, fade/fade, scale-up/scale-down, blur/unblur, rotate-away/rotate-in.
Accessibility is markup, not motion. The link carries an aria-label naming both words; the swap span is aria-hidden. A screen reader hears one coherent label instead of two overlapping words.
Make it yours
- Swap in your own pairs — keep them similar in length or raise
min-w-*. - Slot-machine feel: add
group-hover:tracking-[0.1em]to the incoming word. - Speed:
duration-200reads snappy,duration-500reads considered.
Gotchas — read before shipping
- Without a fixed width the link jumps as the words swap;
min-w-[8ch]is load-bearing. clip-pathon an inline element does nothing — the words areblock.- Keep the
aria-labelin sync with both words, or the accessible name drifts from what is on screen.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Transforms, clip-path and filter are Baseline; the floor is Tailwind v4's generated sheet.