20 CSS Text Gradient Effects 06 / 20
Gradient Text Button Link CSS
Three button patterns — ghost with gradient label, gradient border via mask, and filled gradient — demonstrating every CTA gradient variant.
The code
<div class="tg-06">
<div class="tg-06__panel">
<h2 class="tg-06__heading">Ready to launch?</h2>
<p class="tg-06__sub">Pick the interaction pattern that fits your design system.</p>
<div class="tg-06__grid">
<div class="tg-06__col">
<p class="tg-06__tag">Ghost with gradient label</p>
<a href="#" class="tg-06__btn tg-06__btn--ghost">
<span class="tg-06__label">Get started free</span>
</a>
<a href="#" class="tg-06__btn tg-06__btn--ghost">
<span class="tg-06__label">View documentation →</span>
</a>
</div>
<div class="tg-06__col">
<p class="tg-06__tag">Solid gradient border</p>
<a href="#" class="tg-06__btn tg-06__btn--border">
<span class="tg-06__label">Start building</span>
</a>
<a href="#" class="tg-06__btn tg-06__btn--border">
<span class="tg-06__label">Talk to sales</span>
</a>
</div>
<div class="tg-06__col">
<p class="tg-06__tag">Filled gradient</p>
<a href="#" class="tg-06__btn tg-06__btn--filled">Upgrade to Pro</a>
<a href="#" class="tg-06__btn tg-06__btn--filled tg-06__btn--sm">Learn more</a>
</div>
</div>
</div>
</div> <div class="tg-06">
<div class="tg-06__panel">
<h2 class="tg-06__heading">Ready to launch?</h2>
<p class="tg-06__sub">Pick the interaction pattern that fits your design system.</p>
<div class="tg-06__grid">
<div class="tg-06__col">
<p class="tg-06__tag">Ghost with gradient label</p>
<a href="#" class="tg-06__btn tg-06__btn--ghost">
<span class="tg-06__label">Get started free</span>
</a>
<a href="#" class="tg-06__btn tg-06__btn--ghost">
<span class="tg-06__label">View documentation →</span>
</a>
</div>
<div class="tg-06__col">
<p class="tg-06__tag">Solid gradient border</p>
<a href="#" class="tg-06__btn tg-06__btn--border">
<span class="tg-06__label">Start building</span>
</a>
<a href="#" class="tg-06__btn tg-06__btn--border">
<span class="tg-06__label">Talk to sales</span>
</a>
</div>
<div class="tg-06__col">
<p class="tg-06__tag">Filled gradient</p>
<a href="#" class="tg-06__btn tg-06__btn--filled">Upgrade to Pro</a>
<a href="#" class="tg-06__btn tg-06__btn--filled tg-06__btn--sm">Learn more</a>
</div>
</div>
</div>
</div>.tg-06, .tg-06 *, .tg-06 *::before, .tg-06 *::after { margin:0; padding:0; box-sizing:border-box; }
.tg-06 ::selection { background:#7c3aed; color:#fff; }
.tg-06 {
--g-a: #f59e0b;
--g-b: #ef4444;
--g-c: #ec4899;
--bg: #0c0c10;
--surface: #15151d;
--text: #f1f5f9;
--muted: #64748b;
--border: rgba(255,255,255,.09);
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 48px 24px;
}
.tg-06__panel {
max-width: 640px;
width: 100%;
}
.tg-06__heading {
font-size: clamp(1.6rem, 4vw, 2.5rem);
font-weight: 800;
color: var(--text);
letter-spacing: -.03em;
margin-bottom: 10px;
}
.tg-06__sub {
color: var(--muted);
font-size: .9375rem;
margin-bottom: 36px;
}
.tg-06__grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 28px;
}
.tg-06__col { display: flex; flex-direction: column; gap: 12px; }
.tg-06__tag { font-size: .72rem; font-weight: 600; letter-spacing: .09em; color: var(--muted); margin-bottom: 4px; }
/* Base button */
.tg-06__btn {
display: inline-flex;
align-items: center;
justify-content: center;
text-decoration: none;
font-size: .9rem;
font-weight: 700;
padding: 11px 22px;
border-radius: 9px;
transition: transform .2s, box-shadow .2s, opacity .2s;
cursor: pointer;
}
.tg-06__btn:hover { transform: translateY(-2px); }
/* Ghost: transparent bg, gradient text label */
.tg-06__btn--ghost {
background: transparent;
border: 1.5px solid var(--border);
color: var(--text);
}
.tg-06__btn--ghost .tg-06__label {
background: linear-gradient(90deg, var(--g-a), var(--g-c));
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
.tg-06__btn--ghost:hover { border-color: rgba(239,68,68,.4); }
/* Border gradient: pseudo-element creates gradient border, inner bg clips it */
.tg-06__btn--border {
position: relative;
background: var(--surface);
border: none;
padding: 12px 23px; /* +1 for pseudo border */
isolation: isolate;
}
.tg-06__btn--border::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
padding: 1.5px;
background: linear-gradient(90deg, var(--g-a), var(--g-c));
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: destination-out;
mask-composite: exclude;
pointer-events: none;
}
.tg-06__btn--border .tg-06__label {
background: linear-gradient(90deg, var(--g-a), var(--g-c));
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
/* Filled */
.tg-06__btn--filled {
background: linear-gradient(90deg, var(--g-a), var(--g-b), var(--g-c));
color: #fff;
}
.tg-06__btn--filled:hover { box-shadow: 0 8px 24px rgba(239,68,68,.35); opacity: .9; }
.tg-06__btn--sm { font-size: .8rem; padding: 8px 18px; }
@media (prefers-reduced-motion: reduce) {
.tg-06__btn { transition: none; }
} .tg-06, .tg-06 *, .tg-06 *::before, .tg-06 *::after { margin:0; padding:0; box-sizing:border-box; }
.tg-06 ::selection { background:#7c3aed; color:#fff; }
.tg-06 {
--g-a: #f59e0b;
--g-b: #ef4444;
--g-c: #ec4899;
--bg: #0c0c10;
--surface: #15151d;
--text: #f1f5f9;
--muted: #64748b;
--border: rgba(255,255,255,.09);
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 48px 24px;
}
.tg-06__panel {
max-width: 640px;
width: 100%;
}
.tg-06__heading {
font-size: clamp(1.6rem, 4vw, 2.5rem);
font-weight: 800;
color: var(--text);
letter-spacing: -.03em;
margin-bottom: 10px;
}
.tg-06__sub {
color: var(--muted);
font-size: .9375rem;
margin-bottom: 36px;
}
.tg-06__grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 28px;
}
.tg-06__col { display: flex; flex-direction: column; gap: 12px; }
.tg-06__tag { font-size: .72rem; font-weight: 600; letter-spacing: .09em; color: var(--muted); margin-bottom: 4px; }
/* Base button */
.tg-06__btn {
display: inline-flex;
align-items: center;
justify-content: center;
text-decoration: none;
font-size: .9rem;
font-weight: 700;
padding: 11px 22px;
border-radius: 9px;
transition: transform .2s, box-shadow .2s, opacity .2s;
cursor: pointer;
}
.tg-06__btn:hover { transform: translateY(-2px); }
/* Ghost: transparent bg, gradient text label */
.tg-06__btn--ghost {
background: transparent;
border: 1.5px solid var(--border);
color: var(--text);
}
.tg-06__btn--ghost .tg-06__label {
background: linear-gradient(90deg, var(--g-a), var(--g-c));
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
.tg-06__btn--ghost:hover { border-color: rgba(239,68,68,.4); }
/* Border gradient: pseudo-element creates gradient border, inner bg clips it */
.tg-06__btn--border {
position: relative;
background: var(--surface);
border: none;
padding: 12px 23px; /* +1 for pseudo border */
isolation: isolate;
}
.tg-06__btn--border::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
padding: 1.5px;
background: linear-gradient(90deg, var(--g-a), var(--g-c));
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: destination-out;
mask-composite: exclude;
pointer-events: none;
}
.tg-06__btn--border .tg-06__label {
background: linear-gradient(90deg, var(--g-a), var(--g-c));
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
/* Filled */
.tg-06__btn--filled {
background: linear-gradient(90deg, var(--g-a), var(--g-b), var(--g-c));
color: #fff;
}
.tg-06__btn--filled:hover { box-shadow: 0 8px 24px rgba(239,68,68,.35); opacity: .9; }
.tg-06__btn--sm { font-size: .8rem; padding: 8px 18px; }
@media (prefers-reduced-motion: reduce) {
.tg-06__btn { transition: none; }
}How this works
Three distinct CTA patterns are demonstrated. The ghost button uses a transparent background with a gradient applied only to the inner span via -webkit-background-clip: text. The gradient-border variant uses a ::before pseudo-element with padding: 1.5px and a -webkit-mask composite to paint only the border ring in a gradient, leaving the inner fill flat.
The mask composite technique for gradient borders works by applying the same linear-gradient to a pseudo-element, then using -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0) with mask-composite: exclude to punch out the content area, leaving only the padding ring visible. This is the only pure-CSS method to achieve a true gradient border without SVG.
Customize
- Swap all three button gradients at once by editing the
--g-a,--g-b,--g-cvariables at.tg-06root — ghost label, border, and filled buttons all update. - Increase the gradient border width by raising
padding: 1.5pxon the.tg-06__btn--border::beforepseudo-element —2.5pxgives a more visible ring on dark backgrounds. - Add a glowing box-shadow to the ghost button on hover:
box-shadow: 0 0 20px rgba(239,68,68,.2)pairs well with the existing border-colour transition. - Make the filled button animate by adding
background-size: 200%and abackground-positionkeyframe on the:hoverstate for a shimmer sweep on rollover. - Round all buttons further with
border-radius: 99pxfor a pill style, or reduce to4pxfor a sharper, more technical aesthetic.
Watch out for
- The mask-composite gradient border technique requires
-webkit-mask-composite: destination-outin Safari (notexclude) — include both values to support all browsers:-webkit-mask-composite: destination-out; mask-composite: exclude. - In Firefox, the
mask-composite: excludeapproach requires the mask shorthand to be split into two separate-webkit-mask-imageandmask-imagedeclarations — the combined shorthand is not always processed correctly across all Firefox versions. - Stacking a ghost button and a border-gradient button in the same flex container can cause alignment issues on Safari if both buttons use
padding-based borders; use consistent padding values across all variants.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 69+ | 12.1+ | 83+ | 69+ |
mask-composite: exclude requires -webkit-mask-composite: destination-out in Safari; include both declarations for full coverage.