16 / 20
All 20 in 20 Tailwind CSS Text Gradient
- 01Tailwind CSS Gradient Text Hero Heading
- 02Tailwind Glowing Gradient Text (Web3 Neon Glow)
- 03Tailwind Gradient Text Logo for Navbar
- 04Bold Minimalist Gradient Heading in Tailwind CSS
- 05Tailwind Gradient Text on Hover Animation
- 06Tailwind Gradient Text Button & Gradient Border Button
- 07Tailwind Active Nav Link with Gradient Text
- 08Tailwind Animated Gradient Text (Moving Gradient)
- 09Cyberpunk Neon Gradient Text in Tailwind CSS
- 10Tailwind Metallic Gold Gradient Text Effect
- 11Glassmorphism Card with Gradient Text in Tailwind
- 12Pastel Gradient Text in Tailwind CSS
- 13Tailwind Vertical Gradient Text (Top to Bottom)
- 14Tailwind Radial Gradient Text Effect
- 15Tailwind Rainbow Gradient Text (Multi-Color)
- 16Tailwind Gradient Text with Outline Stroke
- 17Tailwind Gradient Text Fallback with @supports
- 18Tailwind bg-clip-text Gradient Utility Classes Cheat Sheet
- 19Tailwind Gradient Text on Multiline Paragraph
- 20Tailwind Dark Mode Gradient Text Toggle
Tailwind Gradient Text with Outline Stroke
Stroke-only, fill-only and stroke-plus-fill side by side, plus a hollow display word whose outline fills with gradient on hover. Tailwind has no stroke-text utility, so [-webkit-text-stroke:2px_…] and [paint-order:stroke_fill] arbitrary properties do the work — right in the class list.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="ttg-16 w-full min-h-svh grid place-items-center bg-ttg16-bg px-5 py-16 font-ttg16-sans text-ttg16-ink" aria-label="Gradient text with outline stroke demo">
<div class="w-full max-w-3xl">
<p class="font-ttg16-mono text-[11px] tracking-[0.16em] text-ttg16-mut uppercase">Stroke + gradient fill · hover the outline</p>
<h1 class="mt-4 w-fit cursor-default bg-linear-to-r from-ttg16-a via-ttg16-b to-ttg16-c bg-[length:0%_100%] bg-no-repeat bg-clip-text font-ttg16-display text-[clamp(3.5rem,13vw,7.5rem)] leading-[0.95] tracking-[0.02em] text-transparent transition-[background-size] duration-700 ease-out [-webkit-text-stroke:2px_var(--color-ttg16-a)] hover:bg-[length:100%_100%] motion-reduce:transition-none">OUTLINE</h1>
<h2 class="mt-3 w-fit bg-linear-to-r from-ttg16-a via-ttg16-b to-ttg16-c bg-clip-text text-[clamp(1.6rem,5vw,2.8rem)] font-bold tracking-[-0.02em] text-transparent [-webkit-text-stroke:1px_var(--color-ttg16-stroke)] [paint-order:stroke_fill]">Gradient fill + stroke</h2>
<div class="mt-10 grid gap-4 sm:grid-cols-3">
<figure class="grid gap-3 rounded-2xl border border-white/8 bg-white/[0.025] p-5">
<span class="font-ttg16-display text-6xl text-transparent [-webkit-text-stroke:2px_var(--color-ttg16-a)]">Type</span>
<figcaption class="font-ttg16-mono text-[11.5px] text-ttg16-mut">Stroke only<br><span class="text-ttg16-ink/80">text-transparent + stroke</span></figcaption>
</figure>
<figure class="grid gap-3 rounded-2xl border border-white/8 bg-white/[0.025] p-5">
<span class="w-fit bg-linear-to-r from-ttg16-b to-ttg16-c bg-clip-text font-ttg16-display text-6xl text-transparent">Type</span>
<figcaption class="font-ttg16-mono text-[11.5px] text-ttg16-mut">Fill only<br><span class="text-ttg16-ink/80">bg-clip-text</span></figcaption>
</figure>
<figure class="grid gap-3 rounded-2xl border border-white/8 bg-white/[0.025] p-5">
<span class="w-fit bg-linear-to-r from-ttg16-a via-ttg16-b to-ttg16-c bg-clip-text font-ttg16-display text-6xl text-transparent [-webkit-text-stroke:3px_var(--color-ttg16-stroke)] [paint-order:stroke_fill]">Type</span>
<figcaption class="font-ttg16-mono text-[11.5px] text-ttg16-mut">Stroke + fill<br><span class="text-ttg16-ink/80">[paint-order:stroke_fill]</span></figcaption>
</figure>
</div>
</div>
</section><section class="ttg-16 w-full min-h-svh grid place-items-center bg-ttg16-bg px-5 py-16 font-ttg16-sans text-ttg16-ink" aria-label="Gradient text with outline stroke demo">
<div class="w-full max-w-3xl">
<p class="font-ttg16-mono text-[11px] tracking-[0.16em] text-ttg16-mut uppercase">Stroke + gradient fill · hover the outline</p>
<h1 class="mt-4 w-fit cursor-default bg-linear-to-r from-ttg16-a via-ttg16-b to-ttg16-c bg-[length:0%_100%] bg-no-repeat bg-clip-text font-ttg16-display text-[clamp(3.5rem,13vw,7.5rem)] leading-[0.95] tracking-[0.02em] text-transparent transition-[background-size] duration-700 ease-out [-webkit-text-stroke:2px_var(--color-ttg16-a)] hover:bg-[length:100%_100%] motion-reduce:transition-none">OUTLINE</h1>
<h2 class="mt-3 w-fit bg-linear-to-r from-ttg16-a via-ttg16-b to-ttg16-c bg-clip-text text-[clamp(1.6rem,5vw,2.8rem)] font-bold tracking-[-0.02em] text-transparent [-webkit-text-stroke:1px_var(--color-ttg16-stroke)] [paint-order:stroke_fill]">Gradient fill + stroke</h2>
<div class="mt-10 grid gap-4 sm:grid-cols-3">
<figure class="grid gap-3 rounded-2xl border border-white/8 bg-white/[0.025] p-5">
<span class="font-ttg16-display text-6xl text-transparent [-webkit-text-stroke:2px_var(--color-ttg16-a)]">Type</span>
<figcaption class="font-ttg16-mono text-[11.5px] text-ttg16-mut">Stroke only<br><span class="text-ttg16-ink/80">text-transparent + stroke</span></figcaption>
</figure>
<figure class="grid gap-3 rounded-2xl border border-white/8 bg-white/[0.025] p-5">
<span class="w-fit bg-linear-to-r from-ttg16-b to-ttg16-c bg-clip-text font-ttg16-display text-6xl text-transparent">Type</span>
<figcaption class="font-ttg16-mono text-[11.5px] text-ttg16-mut">Fill only<br><span class="text-ttg16-ink/80">bg-clip-text</span></figcaption>
</figure>
<figure class="grid gap-3 rounded-2xl border border-white/8 bg-white/[0.025] p-5">
<span class="w-fit bg-linear-to-r from-ttg16-a via-ttg16-b to-ttg16-c bg-clip-text font-ttg16-display text-6xl text-transparent [-webkit-text-stroke:3px_var(--color-ttg16-stroke)] [paint-order:stroke_fill]">Type</span>
<figcaption class="font-ttg16-mono text-[11.5px] text-ttg16-mut">Stroke + fill<br><span class="text-ttg16-ink/80">[paint-order:stroke_fill]</span></figcaption>
</figure>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-ttg16-bg: #04070b;
--color-ttg16-bg: oklch(0.13 0.012 250);
--color-ttg16-ink: #eef3f8;
--color-ttg16-ink: oklch(0.96 0.008 245);
--color-ttg16-mut: #98a3b3;
--color-ttg16-mut: oklch(0.72 0.025 255);
--color-ttg16-stroke: #ffffff59;
--color-ttg16-stroke: oklch(1 0 0 / 0.35);
--color-ttg16-a: #38bdf8;
--color-ttg16-a: oklch(0.77 0.14 230);
--color-ttg16-b: #8b8ff7;
--color-ttg16-b: oklch(0.68 0.15 280);
--color-ttg16-c: #ea7cf8;
--color-ttg16-c: oklch(0.75 0.19 320);
--font-ttg16-display: 'Archivo Black', system-ui, sans-serif;
--font-ttg16-sans: 'Geist', system-ui, sans-serif;
--font-ttg16-mono: 'Geist Mono', ui-monospace, monospace;
}
.ttg-16 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-ttg16-bg: #04070b;
--color-ttg16-bg: oklch(0.13 0.012 250);
--color-ttg16-ink: #eef3f8;
--color-ttg16-ink: oklch(0.96 0.008 245);
--color-ttg16-mut: #98a3b3;
--color-ttg16-mut: oklch(0.72 0.025 255);
--color-ttg16-stroke: #ffffff59;
--color-ttg16-stroke: oklch(1 0 0 / 0.35);
--color-ttg16-a: #38bdf8;
--color-ttg16-a: oklch(0.77 0.14 230);
--color-ttg16-b: #8b8ff7;
--color-ttg16-b: oklch(0.68 0.15 280);
--color-ttg16-c: #ea7cf8;
--color-ttg16-c: oklch(0.75 0.19 320);
--font-ttg16-display: 'Archivo Black', system-ui, sans-serif;
--font-ttg16-sans: 'Geist', system-ui, sans-serif;
--font-ttg16-mono: 'Geist Mono', ui-monospace, monospace;
}
.ttg-16 {
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-ttg16-bg: #04070b;
--color-ttg16-bg: oklch(0.13 0.012 250);
--color-ttg16-ink: #eef3f8;
--color-ttg16-ink: oklch(0.96 0.008 245);
--color-ttg16-mut: #98a3b3;
--color-ttg16-mut: oklch(0.72 0.025 255);
--color-ttg16-stroke: #ffffff59;
--color-ttg16-stroke: oklch(1 0 0 / 0.35);
--color-ttg16-a: #38bdf8;
--color-ttg16-a: oklch(0.77 0.14 230);
--color-ttg16-b: #8b8ff7;
--color-ttg16-b: oklch(0.68 0.15 280);
--color-ttg16-c: #ea7cf8;
--color-ttg16-c: oklch(0.75 0.19 320);
--font-ttg16-display: 'Archivo Black', system-ui, sans-serif;
--font-ttg16-sans: 'Geist', system-ui, sans-serif;
--font-ttg16-mono: 'Geist Mono', ui-monospace, monospace;
}
.ttg-16 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-ttg16-bg: #04070b;
--color-ttg16-bg: oklch(0.13 0.012 250);
--color-ttg16-ink: #eef3f8;
--color-ttg16-ink: oklch(0.96 0.008 245);
--color-ttg16-mut: #98a3b3;
--color-ttg16-mut: oklch(0.72 0.025 255);
--color-ttg16-stroke: #ffffff59;
--color-ttg16-stroke: oklch(1 0 0 / 0.35);
--color-ttg16-a: #38bdf8;
--color-ttg16-a: oklch(0.77 0.14 230);
--color-ttg16-b: #8b8ff7;
--color-ttg16-b: oklch(0.68 0.15 280);
--color-ttg16-c: #ea7cf8;
--color-ttg16-c: oklch(0.75 0.19 320);
--font-ttg16-display: 'Archivo Black', system-ui, sans-serif;
--font-ttg16-sans: 'Geist', system-ui, sans-serif;
--font-ttg16-mono: 'Geist Mono', ui-monospace, monospace;
}
.ttg-16 {
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=Archivo+Black&family=Geist:wght@400..600&family=Geist+Mono:wght@500&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=Archivo+Black&family=Geist:wght@400..600&family=Geist+Mono:wght@500&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The original declared
-webkit-text-stroketwice on one rule (the first was dead); the port has one arbitrary property per element. - UI upgrade: the hero word is now genuinely hollow and fills with gradient on hover via an animated
background-sizewipe inside the stroke. - UI upgrade: specimens are labelled
<figure>tiles that print the exact utilities; Archivo Black gives strokes enough mass; muted labels rose from 2.6:1 to 7.4:1.
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 Gradient Text with Outline Stroke
Source: https://codefronts.com/motion/tailwind-css-text-gradient/tailwind-gradient-text-with-outline-stroke/
Stroke-only, fill-only and stroke-plus-fill side by side, plus a hollow display word whose outline fills with gradient on hover. Tailwind has no stroke-text utility, so [-webkit-text-stroke:2px_…] and [paint-order:stroke_fill] arbitrary properties do the work — right in the class list.
## HTML
```html
<section class="ttg-16 w-full min-h-svh grid place-items-center bg-ttg16-bg px-5 py-16 font-ttg16-sans text-ttg16-ink" aria-label="Gradient text with outline stroke demo">
<div class="w-full max-w-3xl">
<p class="font-ttg16-mono text-[11px] tracking-[0.16em] text-ttg16-mut uppercase">Stroke + gradient fill · hover the outline</p>
<h1 class="mt-4 w-fit cursor-default bg-linear-to-r from-ttg16-a via-ttg16-b to-ttg16-c bg-[length:0%_100%] bg-no-repeat bg-clip-text font-ttg16-display text-[clamp(3.5rem,13vw,7.5rem)] leading-[0.95] tracking-[0.02em] text-transparent transition-[background-size] duration-700 ease-out [-webkit-text-stroke:2px_var(--color-ttg16-a)] hover:bg-[length:100%_100%] motion-reduce:transition-none">OUTLINE</h1>
<h2 class="mt-3 w-fit bg-linear-to-r from-ttg16-a via-ttg16-b to-ttg16-c bg-clip-text text-[clamp(1.6rem,5vw,2.8rem)] font-bold tracking-[-0.02em] text-transparent [-webkit-text-stroke:1px_var(--color-ttg16-stroke)] [paint-order:stroke_fill]">Gradient fill + stroke</h2>
<div class="mt-10 grid gap-4 sm:grid-cols-3">
<figure class="grid gap-3 rounded-2xl border border-white/8 bg-white/[0.025] p-5">
<span class="font-ttg16-display text-6xl text-transparent [-webkit-text-stroke:2px_var(--color-ttg16-a)]">Type</span>
<figcaption class="font-ttg16-mono text-[11.5px] text-ttg16-mut">Stroke only<br><span class="text-ttg16-ink/80">text-transparent + stroke</span></figcaption>
</figure>
<figure class="grid gap-3 rounded-2xl border border-white/8 bg-white/[0.025] p-5">
<span class="w-fit bg-linear-to-r from-ttg16-b to-ttg16-c bg-clip-text font-ttg16-display text-6xl text-transparent">Type</span>
<figcaption class="font-ttg16-mono text-[11.5px] text-ttg16-mut">Fill only<br><span class="text-ttg16-ink/80">bg-clip-text</span></figcaption>
</figure>
<figure class="grid gap-3 rounded-2xl border border-white/8 bg-white/[0.025] p-5">
<span class="w-fit bg-linear-to-r from-ttg16-a via-ttg16-b to-ttg16-c bg-clip-text font-ttg16-display text-6xl text-transparent [-webkit-text-stroke:3px_var(--color-ttg16-stroke)] [paint-order:stroke_fill]">Type</span>
<figcaption class="font-ttg16-mono text-[11.5px] text-ttg16-mut">Stroke + fill<br><span class="text-ttg16-ink/80">[paint-order:stroke_fill]</span></figcaption>
</figure>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-ttg16-bg: #04070b;
--color-ttg16-bg: oklch(0.13 0.012 250);
--color-ttg16-ink: #eef3f8;
--color-ttg16-ink: oklch(0.96 0.008 245);
--color-ttg16-mut: #98a3b3;
--color-ttg16-mut: oklch(0.72 0.025 255);
--color-ttg16-stroke: #ffffff59;
--color-ttg16-stroke: oklch(1 0 0 / 0.35);
--color-ttg16-a: #38bdf8;
--color-ttg16-a: oklch(0.77 0.14 230);
--color-ttg16-b: #8b8ff7;
--color-ttg16-b: oklch(0.68 0.15 280);
--color-ttg16-c: #ea7cf8;
--color-ttg16-c: oklch(0.75 0.19 320);
--font-ttg16-display: 'Archivo Black', system-ui, sans-serif;
--font-ttg16-sans: 'Geist', system-ui, sans-serif;
--font-ttg16-mono: 'Geist Mono', ui-monospace, monospace;
}
.ttg-16 {
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 Gradient Text with Outline Stroke
Source: https://codefronts.com/motion/tailwind-css-text-gradient/tailwind-gradient-text-with-outline-stroke/
Stroke-only, fill-only and stroke-plus-fill side by side, plus a hollow display word whose outline fills with gradient on hover. Tailwind has no stroke-text utility, so [-webkit-text-stroke:2px_…] and [paint-order:stroke_fill] arbitrary properties do the work — right in the class list.
## HTML
```html
<section class="ttg-16 w-full min-h-svh grid place-items-center bg-ttg16-bg px-5 py-16 font-ttg16-sans text-ttg16-ink" aria-label="Gradient text with outline stroke demo">
<div class="w-full max-w-3xl">
<p class="font-ttg16-mono text-[11px] tracking-[0.16em] text-ttg16-mut uppercase">Stroke + gradient fill · hover the outline</p>
<h1 class="mt-4 w-fit cursor-default bg-linear-to-r from-ttg16-a via-ttg16-b to-ttg16-c bg-[length:0%_100%] bg-no-repeat bg-clip-text font-ttg16-display text-[clamp(3.5rem,13vw,7.5rem)] leading-[0.95] tracking-[0.02em] text-transparent transition-[background-size] duration-700 ease-out [-webkit-text-stroke:2px_var(--color-ttg16-a)] hover:bg-[length:100%_100%] motion-reduce:transition-none">OUTLINE</h1>
<h2 class="mt-3 w-fit bg-linear-to-r from-ttg16-a via-ttg16-b to-ttg16-c bg-clip-text text-[clamp(1.6rem,5vw,2.8rem)] font-bold tracking-[-0.02em] text-transparent [-webkit-text-stroke:1px_var(--color-ttg16-stroke)] [paint-order:stroke_fill]">Gradient fill + stroke</h2>
<div class="mt-10 grid gap-4 sm:grid-cols-3">
<figure class="grid gap-3 rounded-2xl border border-white/8 bg-white/[0.025] p-5">
<span class="font-ttg16-display text-6xl text-transparent [-webkit-text-stroke:2px_var(--color-ttg16-a)]">Type</span>
<figcaption class="font-ttg16-mono text-[11.5px] text-ttg16-mut">Stroke only<br><span class="text-ttg16-ink/80">text-transparent + stroke</span></figcaption>
</figure>
<figure class="grid gap-3 rounded-2xl border border-white/8 bg-white/[0.025] p-5">
<span class="w-fit bg-linear-to-r from-ttg16-b to-ttg16-c bg-clip-text font-ttg16-display text-6xl text-transparent">Type</span>
<figcaption class="font-ttg16-mono text-[11.5px] text-ttg16-mut">Fill only<br><span class="text-ttg16-ink/80">bg-clip-text</span></figcaption>
</figure>
<figure class="grid gap-3 rounded-2xl border border-white/8 bg-white/[0.025] p-5">
<span class="w-fit bg-linear-to-r from-ttg16-a via-ttg16-b to-ttg16-c bg-clip-text font-ttg16-display text-6xl text-transparent [-webkit-text-stroke:3px_var(--color-ttg16-stroke)] [paint-order:stroke_fill]">Type</span>
<figcaption class="font-ttg16-mono text-[11.5px] text-ttg16-mut">Stroke + fill<br><span class="text-ttg16-ink/80">[paint-order:stroke_fill]</span></figcaption>
</figure>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-ttg16-bg: #04070b;
--color-ttg16-bg: oklch(0.13 0.012 250);
--color-ttg16-ink: #eef3f8;
--color-ttg16-ink: oklch(0.96 0.008 245);
--color-ttg16-mut: #98a3b3;
--color-ttg16-mut: oklch(0.72 0.025 255);
--color-ttg16-stroke: #ffffff59;
--color-ttg16-stroke: oklch(1 0 0 / 0.35);
--color-ttg16-a: #38bdf8;
--color-ttg16-a: oklch(0.77 0.14 230);
--color-ttg16-b: #8b8ff7;
--color-ttg16-b: oklch(0.68 0.15 280);
--color-ttg16-c: #ea7cf8;
--color-ttg16-c: oklch(0.75 0.19 320);
--font-ttg16-display: 'Archivo Black', system-ui, sans-serif;
--font-ttg16-sans: 'Geist', system-ui, sans-serif;
--font-ttg16-mono: 'Geist Mono', ui-monospace, monospace;
}
.ttg-16 {
width: 100%;
min-height: 100svh;
}
```How this works
Arbitrary properties fill the gaps. Any CSS declaration can be a class with square brackets; underscores become spaces:
<span class="bg-linear-to-r from-ttg16-a via-ttg16-b to-ttg16-c bg-clip-text text-transparent
[-webkit-text-stroke:1.5px_rgb(255_255_255/0.35)] [paint-order:stroke_fill]">Type</span>Paint order matters. By default the stroke paints over the fill and eats half its width into each glyph. paint-order: stroke fill draws the stroke first, so the gradient fill sits on top and only the outer half of the stroke shows.
The hollow word starts as stroke-only (gradient layer at 0% width) and the gradient wipes in on hover, inside the outline.
Make it yours
- Display sizes above 6rem: use
3pxstrokes so the outline holds at distance. - Crisp white outline on light pages:
[-webkit-text-stroke:1px_white]with a dark gradient fill. - Hard 3D shadow: add
drop-shadow-[3px_3px_0_var(--color-ttg16-c)]to the stroked word. - Thicker hollow look: swap Archivo Black for a condensed heavy face.
Gotchas — read before shipping
-webkit-text-strokeis centred on the glyph edge; above 3px it closes counters in 'e' and 'a' unless you usepaint-order.- Despite the prefix,
-webkit-text-strokeworks in Firefox and Safari — it's the standardised name. - Strokes on variable fonts can show overlap seams at contour joins; static heavy cuts are cleaner.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
paint-order on HTML text: Chrome 123+, Safari 11+, Firefox 60+; older Chrome paints the stroke over the fill.