27 / 30
All 30 in 30 Tailwind CSS Text Hover Effects
- 01Tailwind CSS Animated Underline Hover Effect
- 02Tailwind Liquid Text Fill Hover Animation
- 03Tailwind Gradient Text Hover Effect with bg-clip-text
- 04Tailwind Animated Strikethrough Text Hover Effect
- 05Tailwind Text Swap and Flip Up Hover Effect
- 06Tailwind CSS Glitch Text Hover Effect
- 07Tailwind Neon Glow Text with Flicker Animation
- 08Tailwind Metallic Gold Shimmer Text Effect
- 09Tailwind 3D Text Pop and Lift Hover Effect
- 10Tailwind Staggered Letter Wave Hover Animation
- 11Tailwind Spotlight Text Reveal on Mouse Hover
- 12Tailwind Hover to Reveal Hidden Spoiler Text
- 13Tailwind Blur to Focus Text Hover Effect
- 14Tailwind Magnetic Hover Effect for Buttons and Text
- 15Tailwind Letter Spacing Expand on Hover (Tracking Animation)
- 16Tailwind Outline Text Stroke to Fill Hover Effect
- 17Tailwind Text Scramble and Matrix Decrypt Hover Effect
- 18Tailwind Animated Border Button Hover Effect
- 19Tailwind Elastic Rubber Band Text Hover Animation
- 20Tailwind Variable Font Weight Hover Animation
- 21Tailwind Animated Rainbow Gradient Text on Hover
- 22Tailwind 3D Perspective Tilt Text Hover Effect
- 23Tailwind Smoke Dissolve Text Hover Effect
- 24Tailwind Fire Text Effect with Heat Wave Glow
- 25Tailwind Dynamic Text Shadow that Follows the Cursor
- 26Tailwind Infinite Text Marquee that Speeds Up on Hover
- 27Tailwind Duotone Split Color Text Hover Effect
- 28Tailwind CSS Tooltip on Hover (No JavaScript)
- 29Tailwind SVG Water Ripple Distortion Text Effect
- 30Tailwind Clip-Path Text Reveal Hover Animation
Tailwind Duotone Split Color Text Hover Effect
A risograph poster headline printed in two plates: before: and after: both print attr(data-text), clipped to top and bottom halves. On hover the plates shear sideways and their clips overlap — with mix-blend-multiply, the overlap band overprints into a third ink, exactly like misregistered riso. Nav buttons split left/right.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tth-27 @container w-full min-h-svh grid place-items-center bg-tth27-bg px-5 py-14 font-tth27-sans text-tth27-ink" aria-label="Duotone split color text demo">
<div class="flex w-full max-w-[53.75rem] flex-col items-center gap-[clamp(16px,3cqi,26px)] text-center">
<header class="flex w-full flex-wrap items-center justify-between gap-3.5 border-b-[1.5px] border-tth27-ink pb-3.5">
<p class="text-xs font-bold uppercase tracking-[0.22em] text-tth27-mut">Riso Press — open studio night</p>
<span class="rounded-full border border-tth27-line px-3 py-1.5 font-tth27-mono text-[11px] text-tth27-mut @max-[35rem]:hidden">two plates · one string · attr(data-text)</span>
</header>
<h2 data-text="BASEMENT TAPES" class="relative inline-block whitespace-nowrap font-tth27-display text-[clamp(32px,6.2cqi,64px)] leading-[1.08] tracking-[-0.01em] text-transparent selection:bg-tth27-a/30 selection:text-tth27-ink before:pointer-events-none before:absolute before:inset-0 before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_0_50%_0)] before:transition-[clip-path,translate] before:duration-500 before:ease-[cubic-bezier(.25,.8,.25,1)] before:content-[attr(data-text)] after:pointer-events-none after:absolute after:inset-0 after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(50%_0_0_0)] after:transition-[clip-path,translate] after:duration-500 after:ease-[cubic-bezier(.25,.8,.25,1)] after:content-[attr(data-text)] hover:before:-translate-x-[.045em] hover:before:[clip-path:inset(0_0_40%_0)] hover:after:translate-x-[.045em] hover:after:[clip-path:inset(44%_0_0_0)] motion-reduce:before:transition-none motion-reduce:after:transition-none @max-[40rem]:whitespace-normal">BASEMENT TAPES</h2>
<p class="font-tth27-mono text-[12.5px] tracking-[0.22em] text-tth27-mut">VOL. IX — printed loud, aligned rarely</p>
<nav class="mt-1.5 flex flex-wrap justify-center gap-[clamp(10px,2.4cqi,20px)]" aria-label="Editions">
<a id="tth27-top" href="#tth27-top" data-text="Prints" class="relative grid min-h-[50px] place-items-center rounded border-2 border-tth27-ink bg-tth27-paper px-[26px] text-[17px] font-bold tracking-[0.02em] text-transparent no-underline shadow-[3px_3px_0_var(--color-tth27-ink)] transition-[translate,box-shadow] duration-300 before:absolute before:inset-0 before:grid before:place-items-center before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_50%_0_0)] before:transition-[clip-path,translate] before:duration-400 before:content-[attr(data-text)] after:absolute after:inset-0 after:grid after:place-items-center after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(0_0_0_50%)] after:transition-[clip-path,translate] after:duration-400 after:content-[attr(data-text)] hover:-translate-y-0.5 hover:shadow-[4px_5px_0_var(--color-tth27-ink)] hover:before:-translate-y-[.06em] hover:before:[clip-path:inset(0_40%_0_0)] hover:after:translate-y-[.06em] hover:after:[clip-path:inset(0_0_0_44%)] focus-visible:before:[clip-path:inset(0_40%_0_0)] focus-visible:after:[clip-path:inset(0_0_0_44%)] focus-visible:outline-[2.5px] focus-visible:outline-offset-[3px] focus-visible:outline-tth27-a">Prints</a>
<a href="#tth27-top" data-text="Zines" class="relative grid min-h-[50px] place-items-center rounded border-2 border-tth27-ink bg-tth27-paper px-[26px] text-[17px] font-bold tracking-[0.02em] text-transparent no-underline shadow-[3px_3px_0_var(--color-tth27-ink)] transition-[translate,box-shadow] duration-300 before:absolute before:inset-0 before:grid before:place-items-center before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_50%_0_0)] before:transition-[clip-path,translate] before:duration-400 before:content-[attr(data-text)] after:absolute after:inset-0 after:grid after:place-items-center after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(0_0_0_50%)] after:transition-[clip-path,translate] after:duration-400 after:content-[attr(data-text)] hover:-translate-y-0.5 hover:shadow-[4px_5px_0_var(--color-tth27-ink)] hover:before:-translate-y-[.06em] hover:before:[clip-path:inset(0_40%_0_0)] hover:after:translate-y-[.06em] hover:after:[clip-path:inset(0_0_0_44%)] focus-visible:before:[clip-path:inset(0_40%_0_0)] focus-visible:after:[clip-path:inset(0_0_0_44%)] focus-visible:outline-[2.5px] focus-visible:outline-offset-[3px] focus-visible:outline-tth27-a">Zines</a>
<a href="#tth27-top" data-text="Posters" class="relative grid min-h-[50px] place-items-center rounded border-2 border-tth27-ink bg-tth27-paper px-[26px] text-[17px] font-bold tracking-[0.02em] text-transparent no-underline shadow-[3px_3px_0_var(--color-tth27-ink)] transition-[translate,box-shadow] duration-300 before:absolute before:inset-0 before:grid before:place-items-center before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_50%_0_0)] before:transition-[clip-path,translate] before:duration-400 before:content-[attr(data-text)] after:absolute after:inset-0 after:grid after:place-items-center after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(0_0_0_50%)] after:transition-[clip-path,translate] after:duration-400 after:content-[attr(data-text)] hover:-translate-y-0.5 hover:shadow-[4px_5px_0_var(--color-tth27-ink)] hover:before:-translate-y-[.06em] hover:before:[clip-path:inset(0_40%_0_0)] hover:after:translate-y-[.06em] hover:after:[clip-path:inset(0_0_0_44%)] focus-visible:before:[clip-path:inset(0_40%_0_0)] focus-visible:after:[clip-path:inset(0_0_0_44%)] focus-visible:outline-[2.5px] focus-visible:outline-offset-[3px] focus-visible:outline-tth27-a">Posters</a>
</nav>
<p class="max-w-[60ch] text-[12.5px] leading-[1.7] text-tth27-mut">Hover the headline: the plates shear apart and their clips overlap — <code class="rounded bg-tth27-chip px-1.5 py-px font-tth27-mono text-[0.9em]">mix-blend-multiply</code> overprints the band into a third ink. Links split left/right instead.</p>
</div>
</section><section class="tth-27 @container w-full min-h-svh grid place-items-center bg-tth27-bg px-5 py-14 font-tth27-sans text-tth27-ink" aria-label="Duotone split color text demo">
<div class="flex w-full max-w-[53.75rem] flex-col items-center gap-[clamp(16px,3cqi,26px)] text-center">
<header class="flex w-full flex-wrap items-center justify-between gap-3.5 border-b-[1.5px] border-tth27-ink pb-3.5">
<p class="text-xs font-bold uppercase tracking-[0.22em] text-tth27-mut">Riso Press — open studio night</p>
<span class="rounded-full border border-tth27-line px-3 py-1.5 font-tth27-mono text-[11px] text-tth27-mut @max-[35rem]:hidden">two plates · one string · attr(data-text)</span>
</header>
<h2 data-text="BASEMENT TAPES" class="relative inline-block whitespace-nowrap font-tth27-display text-[clamp(32px,6.2cqi,64px)] leading-[1.08] tracking-[-0.01em] text-transparent selection:bg-tth27-a/30 selection:text-tth27-ink before:pointer-events-none before:absolute before:inset-0 before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_0_50%_0)] before:transition-[clip-path,translate] before:duration-500 before:ease-[cubic-bezier(.25,.8,.25,1)] before:content-[attr(data-text)] after:pointer-events-none after:absolute after:inset-0 after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(50%_0_0_0)] after:transition-[clip-path,translate] after:duration-500 after:ease-[cubic-bezier(.25,.8,.25,1)] after:content-[attr(data-text)] hover:before:-translate-x-[.045em] hover:before:[clip-path:inset(0_0_40%_0)] hover:after:translate-x-[.045em] hover:after:[clip-path:inset(44%_0_0_0)] motion-reduce:before:transition-none motion-reduce:after:transition-none @max-[40rem]:whitespace-normal">BASEMENT TAPES</h2>
<p class="font-tth27-mono text-[12.5px] tracking-[0.22em] text-tth27-mut">VOL. IX — printed loud, aligned rarely</p>
<nav class="mt-1.5 flex flex-wrap justify-center gap-[clamp(10px,2.4cqi,20px)]" aria-label="Editions">
<a id="tth27-top" href="#tth27-top" data-text="Prints" class="relative grid min-h-[50px] place-items-center rounded border-2 border-tth27-ink bg-tth27-paper px-[26px] text-[17px] font-bold tracking-[0.02em] text-transparent no-underline shadow-[3px_3px_0_var(--color-tth27-ink)] transition-[translate,box-shadow] duration-300 before:absolute before:inset-0 before:grid before:place-items-center before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_50%_0_0)] before:transition-[clip-path,translate] before:duration-400 before:content-[attr(data-text)] after:absolute after:inset-0 after:grid after:place-items-center after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(0_0_0_50%)] after:transition-[clip-path,translate] after:duration-400 after:content-[attr(data-text)] hover:-translate-y-0.5 hover:shadow-[4px_5px_0_var(--color-tth27-ink)] hover:before:-translate-y-[.06em] hover:before:[clip-path:inset(0_40%_0_0)] hover:after:translate-y-[.06em] hover:after:[clip-path:inset(0_0_0_44%)] focus-visible:before:[clip-path:inset(0_40%_0_0)] focus-visible:after:[clip-path:inset(0_0_0_44%)] focus-visible:outline-[2.5px] focus-visible:outline-offset-[3px] focus-visible:outline-tth27-a">Prints</a>
<a href="#tth27-top" data-text="Zines" class="relative grid min-h-[50px] place-items-center rounded border-2 border-tth27-ink bg-tth27-paper px-[26px] text-[17px] font-bold tracking-[0.02em] text-transparent no-underline shadow-[3px_3px_0_var(--color-tth27-ink)] transition-[translate,box-shadow] duration-300 before:absolute before:inset-0 before:grid before:place-items-center before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_50%_0_0)] before:transition-[clip-path,translate] before:duration-400 before:content-[attr(data-text)] after:absolute after:inset-0 after:grid after:place-items-center after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(0_0_0_50%)] after:transition-[clip-path,translate] after:duration-400 after:content-[attr(data-text)] hover:-translate-y-0.5 hover:shadow-[4px_5px_0_var(--color-tth27-ink)] hover:before:-translate-y-[.06em] hover:before:[clip-path:inset(0_40%_0_0)] hover:after:translate-y-[.06em] hover:after:[clip-path:inset(0_0_0_44%)] focus-visible:before:[clip-path:inset(0_40%_0_0)] focus-visible:after:[clip-path:inset(0_0_0_44%)] focus-visible:outline-[2.5px] focus-visible:outline-offset-[3px] focus-visible:outline-tth27-a">Zines</a>
<a href="#tth27-top" data-text="Posters" class="relative grid min-h-[50px] place-items-center rounded border-2 border-tth27-ink bg-tth27-paper px-[26px] text-[17px] font-bold tracking-[0.02em] text-transparent no-underline shadow-[3px_3px_0_var(--color-tth27-ink)] transition-[translate,box-shadow] duration-300 before:absolute before:inset-0 before:grid before:place-items-center before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_50%_0_0)] before:transition-[clip-path,translate] before:duration-400 before:content-[attr(data-text)] after:absolute after:inset-0 after:grid after:place-items-center after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(0_0_0_50%)] after:transition-[clip-path,translate] after:duration-400 after:content-[attr(data-text)] hover:-translate-y-0.5 hover:shadow-[4px_5px_0_var(--color-tth27-ink)] hover:before:-translate-y-[.06em] hover:before:[clip-path:inset(0_40%_0_0)] hover:after:translate-y-[.06em] hover:after:[clip-path:inset(0_0_0_44%)] focus-visible:before:[clip-path:inset(0_40%_0_0)] focus-visible:after:[clip-path:inset(0_0_0_44%)] focus-visible:outline-[2.5px] focus-visible:outline-offset-[3px] focus-visible:outline-tth27-a">Posters</a>
</nav>
<p class="max-w-[60ch] text-[12.5px] leading-[1.7] text-tth27-mut">Hover the headline: the plates shear apart and their clips overlap — <code class="rounded bg-tth27-chip px-1.5 py-px font-tth27-mono text-[0.9em]">mix-blend-multiply</code> overprints the band into a third ink. Links split left/right instead.</p>
</div>
</section>@import "tailwindcss";
@theme {
--color-tth27-bg: #f5f1e6;
--color-tth27-bg: oklch(0.955 0.012 85);
--color-tth27-paper: #fcfaf5;
--color-tth27-paper: oklch(0.99 0.004 85);
--color-tth27-chip: #e7e1d4;
--color-tth27-chip: oklch(0.9 0.01 80);
--color-tth27-ink: #241f1a;
--color-tth27-ink: oklch(0.24 0.01 60);
--color-tth27-mut: #685f56;
--color-tth27-mut: oklch(0.48 0.02 60);
--color-tth27-line: #d8d0c2;
--color-tth27-line: oklch(0.85 0.015 70);
--color-tth27-a: #e3352b;
--color-tth27-a: oklch(0.6 0.22 28);
--color-tth27-b: #2c5bd1;
--color-tth27-b: oklch(0.52 0.18 262);
--font-tth27-display: 'Dela Gothic One', system-ui, sans-serif;
--font-tth27-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tth27-mono: 'Space Mono', ui-monospace, monospace;
}
.tth-27 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tth27-bg: #f5f1e6;
--color-tth27-bg: oklch(0.955 0.012 85);
--color-tth27-paper: #fcfaf5;
--color-tth27-paper: oklch(0.99 0.004 85);
--color-tth27-chip: #e7e1d4;
--color-tth27-chip: oklch(0.9 0.01 80);
--color-tth27-ink: #241f1a;
--color-tth27-ink: oklch(0.24 0.01 60);
--color-tth27-mut: #685f56;
--color-tth27-mut: oklch(0.48 0.02 60);
--color-tth27-line: #d8d0c2;
--color-tth27-line: oklch(0.85 0.015 70);
--color-tth27-a: #e3352b;
--color-tth27-a: oklch(0.6 0.22 28);
--color-tth27-b: #2c5bd1;
--color-tth27-b: oklch(0.52 0.18 262);
--font-tth27-display: 'Dela Gothic One', system-ui, sans-serif;
--font-tth27-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tth27-mono: 'Space Mono', ui-monospace, monospace;
}
.tth-27 {
width: 100%;
min-height: 100svh;
}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-tth27-bg: #f5f1e6;
--color-tth27-bg: oklch(0.955 0.012 85);
--color-tth27-paper: #fcfaf5;
--color-tth27-paper: oklch(0.99 0.004 85);
--color-tth27-chip: #e7e1d4;
--color-tth27-chip: oklch(0.9 0.01 80);
--color-tth27-ink: #241f1a;
--color-tth27-ink: oklch(0.24 0.01 60);
--color-tth27-mut: #685f56;
--color-tth27-mut: oklch(0.48 0.02 60);
--color-tth27-line: #d8d0c2;
--color-tth27-line: oklch(0.85 0.015 70);
--color-tth27-a: #e3352b;
--color-tth27-a: oklch(0.6 0.22 28);
--color-tth27-b: #2c5bd1;
--color-tth27-b: oklch(0.52 0.18 262);
--font-tth27-display: 'Dela Gothic One', system-ui, sans-serif;
--font-tth27-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tth27-mono: 'Space Mono', ui-monospace, monospace;
}
.tth-27 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tth27-bg: #f5f1e6;
--color-tth27-bg: oklch(0.955 0.012 85);
--color-tth27-paper: #fcfaf5;
--color-tth27-paper: oklch(0.99 0.004 85);
--color-tth27-chip: #e7e1d4;
--color-tth27-chip: oklch(0.9 0.01 80);
--color-tth27-ink: #241f1a;
--color-tth27-ink: oklch(0.24 0.01 60);
--color-tth27-mut: #685f56;
--color-tth27-mut: oklch(0.48 0.02 60);
--color-tth27-line: #d8d0c2;
--color-tth27-line: oklch(0.85 0.015 70);
--color-tth27-a: #e3352b;
--color-tth27-a: oklch(0.6 0.22 28);
--color-tth27-b: #2c5bd1;
--color-tth27-b: oklch(0.52 0.18 262);
--font-tth27-display: 'Dela Gothic One', system-ui, sans-serif;
--font-tth27-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tth27-mono: 'Space Mono', ui-monospace, monospace;
}
.tth-27 {
width: 100%;
min-height: 100svh;
}<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=Dela+Gothic+One&family=Space+Grotesk:wght@500;700&family=Space+Mono:wght@400;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=Dela+Gothic+One&family=Space+Grotesk:wght@500;700&family=Space+Mono:wght@400;700&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- Ten pseudo-element rules became
before:/after:class lists with arbitrary[clip-path:…]values; the@supportstransparent-text guard was dropped because v4's floor guarantees support. ::selectionbecame theselection:variant.- UI upgrade from the CSS original: hover now makes the two plates overlap (40%/44% insets) with
mix-blend-multiply, so the seam overprints into a third ink — real riso behaviour, not just two halves sliding. - UI upgrade: nav buttons got a hard print-shadow lift, and Dela Gothic One gives the poster its weight.
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 Duotone Split Color Text Hover Effect
Source: https://codefronts.com/motion/tailwind-css-text-hover-effects/tailwind-duotone-split-color-text-hover-effect/
A risograph poster headline printed in two plates: before: and after: both print attr(data-text), clipped to top and bottom halves. On hover the plates shear sideways and their clips overlap — with mix-blend-multiply, the overlap band overprints into a third ink, exactly like misregistered riso. Nav buttons split left/right.
## HTML
```html
<section class="tth-27 @container w-full min-h-svh grid place-items-center bg-tth27-bg px-5 py-14 font-tth27-sans text-tth27-ink" aria-label="Duotone split color text demo">
<div class="flex w-full max-w-[53.75rem] flex-col items-center gap-[clamp(16px,3cqi,26px)] text-center">
<header class="flex w-full flex-wrap items-center justify-between gap-3.5 border-b-[1.5px] border-tth27-ink pb-3.5">
<p class="text-xs font-bold uppercase tracking-[0.22em] text-tth27-mut">Riso Press — open studio night</p>
<span class="rounded-full border border-tth27-line px-3 py-1.5 font-tth27-mono text-[11px] text-tth27-mut @max-[35rem]:hidden">two plates · one string · attr(data-text)</span>
</header>
<h2 data-text="BASEMENT TAPES" class="relative inline-block whitespace-nowrap font-tth27-display text-[clamp(32px,6.2cqi,64px)] leading-[1.08] tracking-[-0.01em] text-transparent selection:bg-tth27-a/30 selection:text-tth27-ink before:pointer-events-none before:absolute before:inset-0 before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_0_50%_0)] before:transition-[clip-path,translate] before:duration-500 before:ease-[cubic-bezier(.25,.8,.25,1)] before:content-[attr(data-text)] after:pointer-events-none after:absolute after:inset-0 after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(50%_0_0_0)] after:transition-[clip-path,translate] after:duration-500 after:ease-[cubic-bezier(.25,.8,.25,1)] after:content-[attr(data-text)] hover:before:-translate-x-[.045em] hover:before:[clip-path:inset(0_0_40%_0)] hover:after:translate-x-[.045em] hover:after:[clip-path:inset(44%_0_0_0)] motion-reduce:before:transition-none motion-reduce:after:transition-none @max-[40rem]:whitespace-normal">BASEMENT TAPES</h2>
<p class="font-tth27-mono text-[12.5px] tracking-[0.22em] text-tth27-mut">VOL. IX — printed loud, aligned rarely</p>
<nav class="mt-1.5 flex flex-wrap justify-center gap-[clamp(10px,2.4cqi,20px)]" aria-label="Editions">
<a id="tth27-top" href="#tth27-top" data-text="Prints" class="relative grid min-h-[50px] place-items-center rounded border-2 border-tth27-ink bg-tth27-paper px-[26px] text-[17px] font-bold tracking-[0.02em] text-transparent no-underline shadow-[3px_3px_0_var(--color-tth27-ink)] transition-[translate,box-shadow] duration-300 before:absolute before:inset-0 before:grid before:place-items-center before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_50%_0_0)] before:transition-[clip-path,translate] before:duration-400 before:content-[attr(data-text)] after:absolute after:inset-0 after:grid after:place-items-center after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(0_0_0_50%)] after:transition-[clip-path,translate] after:duration-400 after:content-[attr(data-text)] hover:-translate-y-0.5 hover:shadow-[4px_5px_0_var(--color-tth27-ink)] hover:before:-translate-y-[.06em] hover:before:[clip-path:inset(0_40%_0_0)] hover:after:translate-y-[.06em] hover:after:[clip-path:inset(0_0_0_44%)] focus-visible:before:[clip-path:inset(0_40%_0_0)] focus-visible:after:[clip-path:inset(0_0_0_44%)] focus-visible:outline-[2.5px] focus-visible:outline-offset-[3px] focus-visible:outline-tth27-a">Prints</a>
<a href="#tth27-top" data-text="Zines" class="relative grid min-h-[50px] place-items-center rounded border-2 border-tth27-ink bg-tth27-paper px-[26px] text-[17px] font-bold tracking-[0.02em] text-transparent no-underline shadow-[3px_3px_0_var(--color-tth27-ink)] transition-[translate,box-shadow] duration-300 before:absolute before:inset-0 before:grid before:place-items-center before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_50%_0_0)] before:transition-[clip-path,translate] before:duration-400 before:content-[attr(data-text)] after:absolute after:inset-0 after:grid after:place-items-center after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(0_0_0_50%)] after:transition-[clip-path,translate] after:duration-400 after:content-[attr(data-text)] hover:-translate-y-0.5 hover:shadow-[4px_5px_0_var(--color-tth27-ink)] hover:before:-translate-y-[.06em] hover:before:[clip-path:inset(0_40%_0_0)] hover:after:translate-y-[.06em] hover:after:[clip-path:inset(0_0_0_44%)] focus-visible:before:[clip-path:inset(0_40%_0_0)] focus-visible:after:[clip-path:inset(0_0_0_44%)] focus-visible:outline-[2.5px] focus-visible:outline-offset-[3px] focus-visible:outline-tth27-a">Zines</a>
<a href="#tth27-top" data-text="Posters" class="relative grid min-h-[50px] place-items-center rounded border-2 border-tth27-ink bg-tth27-paper px-[26px] text-[17px] font-bold tracking-[0.02em] text-transparent no-underline shadow-[3px_3px_0_var(--color-tth27-ink)] transition-[translate,box-shadow] duration-300 before:absolute before:inset-0 before:grid before:place-items-center before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_50%_0_0)] before:transition-[clip-path,translate] before:duration-400 before:content-[attr(data-text)] after:absolute after:inset-0 after:grid after:place-items-center after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(0_0_0_50%)] after:transition-[clip-path,translate] after:duration-400 after:content-[attr(data-text)] hover:-translate-y-0.5 hover:shadow-[4px_5px_0_var(--color-tth27-ink)] hover:before:-translate-y-[.06em] hover:before:[clip-path:inset(0_40%_0_0)] hover:after:translate-y-[.06em] hover:after:[clip-path:inset(0_0_0_44%)] focus-visible:before:[clip-path:inset(0_40%_0_0)] focus-visible:after:[clip-path:inset(0_0_0_44%)] focus-visible:outline-[2.5px] focus-visible:outline-offset-[3px] focus-visible:outline-tth27-a">Posters</a>
</nav>
<p class="max-w-[60ch] text-[12.5px] leading-[1.7] text-tth27-mut">Hover the headline: the plates shear apart and their clips overlap — <code class="rounded bg-tth27-chip px-1.5 py-px font-tth27-mono text-[0.9em]">mix-blend-multiply</code> overprints the band into a third ink. Links split left/right instead.</p>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tth27-bg: #f5f1e6;
--color-tth27-bg: oklch(0.955 0.012 85);
--color-tth27-paper: #fcfaf5;
--color-tth27-paper: oklch(0.99 0.004 85);
--color-tth27-chip: #e7e1d4;
--color-tth27-chip: oklch(0.9 0.01 80);
--color-tth27-ink: #241f1a;
--color-tth27-ink: oklch(0.24 0.01 60);
--color-tth27-mut: #685f56;
--color-tth27-mut: oklch(0.48 0.02 60);
--color-tth27-line: #d8d0c2;
--color-tth27-line: oklch(0.85 0.015 70);
--color-tth27-a: #e3352b;
--color-tth27-a: oklch(0.6 0.22 28);
--color-tth27-b: #2c5bd1;
--color-tth27-b: oklch(0.52 0.18 262);
--font-tth27-display: 'Dela Gothic One', system-ui, sans-serif;
--font-tth27-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tth27-mono: 'Space Mono', ui-monospace, monospace;
}
.tth-27 {
width: 100%;
min-height: 100svh;
}
```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 Duotone Split Color Text Hover Effect
Source: https://codefronts.com/motion/tailwind-css-text-hover-effects/tailwind-duotone-split-color-text-hover-effect/
A risograph poster headline printed in two plates: before: and after: both print attr(data-text), clipped to top and bottom halves. On hover the plates shear sideways and their clips overlap — with mix-blend-multiply, the overlap band overprints into a third ink, exactly like misregistered riso. Nav buttons split left/right.
## HTML
```html
<section class="tth-27 @container w-full min-h-svh grid place-items-center bg-tth27-bg px-5 py-14 font-tth27-sans text-tth27-ink" aria-label="Duotone split color text demo">
<div class="flex w-full max-w-[53.75rem] flex-col items-center gap-[clamp(16px,3cqi,26px)] text-center">
<header class="flex w-full flex-wrap items-center justify-between gap-3.5 border-b-[1.5px] border-tth27-ink pb-3.5">
<p class="text-xs font-bold uppercase tracking-[0.22em] text-tth27-mut">Riso Press — open studio night</p>
<span class="rounded-full border border-tth27-line px-3 py-1.5 font-tth27-mono text-[11px] text-tth27-mut @max-[35rem]:hidden">two plates · one string · attr(data-text)</span>
</header>
<h2 data-text="BASEMENT TAPES" class="relative inline-block whitespace-nowrap font-tth27-display text-[clamp(32px,6.2cqi,64px)] leading-[1.08] tracking-[-0.01em] text-transparent selection:bg-tth27-a/30 selection:text-tth27-ink before:pointer-events-none before:absolute before:inset-0 before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_0_50%_0)] before:transition-[clip-path,translate] before:duration-500 before:ease-[cubic-bezier(.25,.8,.25,1)] before:content-[attr(data-text)] after:pointer-events-none after:absolute after:inset-0 after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(50%_0_0_0)] after:transition-[clip-path,translate] after:duration-500 after:ease-[cubic-bezier(.25,.8,.25,1)] after:content-[attr(data-text)] hover:before:-translate-x-[.045em] hover:before:[clip-path:inset(0_0_40%_0)] hover:after:translate-x-[.045em] hover:after:[clip-path:inset(44%_0_0_0)] motion-reduce:before:transition-none motion-reduce:after:transition-none @max-[40rem]:whitespace-normal">BASEMENT TAPES</h2>
<p class="font-tth27-mono text-[12.5px] tracking-[0.22em] text-tth27-mut">VOL. IX — printed loud, aligned rarely</p>
<nav class="mt-1.5 flex flex-wrap justify-center gap-[clamp(10px,2.4cqi,20px)]" aria-label="Editions">
<a id="tth27-top" href="#tth27-top" data-text="Prints" class="relative grid min-h-[50px] place-items-center rounded border-2 border-tth27-ink bg-tth27-paper px-[26px] text-[17px] font-bold tracking-[0.02em] text-transparent no-underline shadow-[3px_3px_0_var(--color-tth27-ink)] transition-[translate,box-shadow] duration-300 before:absolute before:inset-0 before:grid before:place-items-center before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_50%_0_0)] before:transition-[clip-path,translate] before:duration-400 before:content-[attr(data-text)] after:absolute after:inset-0 after:grid after:place-items-center after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(0_0_0_50%)] after:transition-[clip-path,translate] after:duration-400 after:content-[attr(data-text)] hover:-translate-y-0.5 hover:shadow-[4px_5px_0_var(--color-tth27-ink)] hover:before:-translate-y-[.06em] hover:before:[clip-path:inset(0_40%_0_0)] hover:after:translate-y-[.06em] hover:after:[clip-path:inset(0_0_0_44%)] focus-visible:before:[clip-path:inset(0_40%_0_0)] focus-visible:after:[clip-path:inset(0_0_0_44%)] focus-visible:outline-[2.5px] focus-visible:outline-offset-[3px] focus-visible:outline-tth27-a">Prints</a>
<a href="#tth27-top" data-text="Zines" class="relative grid min-h-[50px] place-items-center rounded border-2 border-tth27-ink bg-tth27-paper px-[26px] text-[17px] font-bold tracking-[0.02em] text-transparent no-underline shadow-[3px_3px_0_var(--color-tth27-ink)] transition-[translate,box-shadow] duration-300 before:absolute before:inset-0 before:grid before:place-items-center before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_50%_0_0)] before:transition-[clip-path,translate] before:duration-400 before:content-[attr(data-text)] after:absolute after:inset-0 after:grid after:place-items-center after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(0_0_0_50%)] after:transition-[clip-path,translate] after:duration-400 after:content-[attr(data-text)] hover:-translate-y-0.5 hover:shadow-[4px_5px_0_var(--color-tth27-ink)] hover:before:-translate-y-[.06em] hover:before:[clip-path:inset(0_40%_0_0)] hover:after:translate-y-[.06em] hover:after:[clip-path:inset(0_0_0_44%)] focus-visible:before:[clip-path:inset(0_40%_0_0)] focus-visible:after:[clip-path:inset(0_0_0_44%)] focus-visible:outline-[2.5px] focus-visible:outline-offset-[3px] focus-visible:outline-tth27-a">Zines</a>
<a href="#tth27-top" data-text="Posters" class="relative grid min-h-[50px] place-items-center rounded border-2 border-tth27-ink bg-tth27-paper px-[26px] text-[17px] font-bold tracking-[0.02em] text-transparent no-underline shadow-[3px_3px_0_var(--color-tth27-ink)] transition-[translate,box-shadow] duration-300 before:absolute before:inset-0 before:grid before:place-items-center before:text-tth27-a before:mix-blend-multiply before:[clip-path:inset(0_50%_0_0)] before:transition-[clip-path,translate] before:duration-400 before:content-[attr(data-text)] after:absolute after:inset-0 after:grid after:place-items-center after:text-tth27-b after:mix-blend-multiply after:[clip-path:inset(0_0_0_50%)] after:transition-[clip-path,translate] after:duration-400 after:content-[attr(data-text)] hover:-translate-y-0.5 hover:shadow-[4px_5px_0_var(--color-tth27-ink)] hover:before:-translate-y-[.06em] hover:before:[clip-path:inset(0_40%_0_0)] hover:after:translate-y-[.06em] hover:after:[clip-path:inset(0_0_0_44%)] focus-visible:before:[clip-path:inset(0_40%_0_0)] focus-visible:after:[clip-path:inset(0_0_0_44%)] focus-visible:outline-[2.5px] focus-visible:outline-offset-[3px] focus-visible:outline-tth27-a">Posters</a>
</nav>
<p class="max-w-[60ch] text-[12.5px] leading-[1.7] text-tth27-mut">Hover the headline: the plates shear apart and their clips overlap — <code class="rounded bg-tth27-chip px-1.5 py-px font-tth27-mono text-[0.9em]">mix-blend-multiply</code> overprints the band into a third ink. Links split left/right instead.</p>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tth27-bg: #f5f1e6;
--color-tth27-bg: oklch(0.955 0.012 85);
--color-tth27-paper: #fcfaf5;
--color-tth27-paper: oklch(0.99 0.004 85);
--color-tth27-chip: #e7e1d4;
--color-tth27-chip: oklch(0.9 0.01 80);
--color-tth27-ink: #241f1a;
--color-tth27-ink: oklch(0.24 0.01 60);
--color-tth27-mut: #685f56;
--color-tth27-mut: oklch(0.48 0.02 60);
--color-tth27-line: #d8d0c2;
--color-tth27-line: oklch(0.85 0.015 70);
--color-tth27-a: #e3352b;
--color-tth27-a: oklch(0.6 0.22 28);
--color-tth27-b: #2c5bd1;
--color-tth27-b: oklch(0.52 0.18 262);
--font-tth27-display: 'Dela Gothic One', system-ui, sans-serif;
--font-tth27-sans: 'Space Grotesk', system-ui, sans-serif;
--font-tth27-mono: 'Space Mono', ui-monospace, monospace;
}
.tth-27 {
width: 100%;
min-height: 100svh;
}
```How this works
Two plates, one string. The heading's own text is transparent (it exists for selection, search and screen readers). Two pseudo-elements print the same string from data-text, each in one ink and each clipped to half:
<h2 data-text="BASEMENT TAPES" class="text-transparent
before:content-[attr(data-text)] before:[clip-path:inset(0_0_50%_0)]
after:content-[attr(data-text)] after:[clip-path:inset(50%_0_0_0)]
hover:before:[clip-path:inset(0_0_40%_0)] hover:after:[clip-path:inset(44%_0_0_0)]">Matching shapes tween. inset() to inset() interpolates smoothly. On hover the clips grow past each other, leaving a band from 44% to 60% where both plates print — multiplied, red over blue makes a deep plum.
Make it yours
- Ink pair:
--color-tth27-a/b— fluorescent pink + teal is the classic riso pair. - Vertical split for the headline: swap insets to
inset(0_50%_0_0)/inset(0_0_0_50%). - Bigger misregistration: raise the translates to
.08em.
Gotchas — read before shipping
data-textmust match the visible text exactly.- Multiply only reads on light grounds; on dark stages use
mix-blend-screen. - Long headlines that wrap need
@max-[35rem]:whitespace-normal— the pseudo copies wrap identically because they share the box.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Universal; the floor is Tailwind v4's sheet.