20 CSS Text Gradient Effects 16 / 20

CSS Text Gradient with Text Stroke Outline

Combines -webkit-text-stroke with background-clip gradient fill, demonstrating stroke-only, fill-only, and stroke-plus-fill patterns side by side.

Pure CSS MIT licensed
Live Demo Open in tab
Open in playground

The code

<div class="tg-16">
  <div class="tg-16__wrapper">
    <p class="tg-16__label">COMBINING STROKE + GRADIENT FILL</p>
    <h1 class="tg-16__outlined">OUTLINE</h1>
    <h2 class="tg-16__stroked">Gradient Fill + Stroke</h2>
    <div class="tg-16__grid">
      <div class="tg-16__example">
        <span class="tg-16__ex-lbl">Stroke only</span>
        <span class="tg-16__stroke-only">Type</span>
      </div>
      <div class="tg-16__example">
        <span class="tg-16__ex-lbl">Fill only</span>
        <span class="tg-16__fill-only">Type</span>
      </div>
      <div class="tg-16__example">
        <span class="tg-16__ex-lbl">Stroke + Fill</span>
        <span class="tg-16__both">Type</span>
      </div>
    </div>
    <p class="tg-16__note">Apply <code>-webkit-text-stroke</code> first, then layer gradient via <code>background-clip: text</code>. The stroke paints on top of the clipped gradient fill.</p>
  </div>
</div>
.tg-16, .tg-16 *, .tg-16 *::before, .tg-16 *::after { margin:0; padding:0; box-sizing:border-box; }
.tg-16 ::selection { background:#0f172a; color:#e0f2fe; }

.tg-16 {
  --g-a: #38bdf8;
  --g-b: #818cf8;
  --g-c: #e879f9;
  --bg: #030609;
  --text: #f1f5f9;
  --muted: #475569;
  --border: rgba(255,255,255,.07);
  font-family: system-ui, -apple-system, sans-serif;
  background: var(--bg);
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 44px 24px;
}

.tg-16__wrapper { max-width: 640px; width: 100%; }

.tg-16__label {
  font-size: .65rem;
  font-weight: 700;
  letter-spacing: .16em;
  color: var(--muted);
  margin-bottom: 16px;
}

/*
  Outlined text: -webkit-text-stroke sets a stroke colour/width,
  and -webkit-text-fill-color: transparent makes the fill invisible,
  leaving only the outline. We can layer a gradient behind via background-clip
  to colour the visible stroke area.
*/
.tg-16__outlined {
  font-size: clamp(3.5rem, 12vw, 6.5rem);
  font-weight: 900;
  letter-spacing: .04em;
  line-height: 1;
  -webkit-text-stroke: 2px transparent;
  /* Use background + clip to colour the stroke itself */
  background: linear-gradient(90deg, var(--g-a), var(--g-b), var(--g-c));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  /* Add stroke on top via paint-order if supported */
  paint-order: stroke fill;
  -webkit-text-stroke: 2px rgba(56,189,248,.6);
  margin-bottom: 8px;
  display: block;
}

/*
  Fill + stroke combined: gradient fill is applied through background-clip,
  then -webkit-text-stroke paints over it. Use a semi-transparent or
  complementary stroke colour to preserve the gradient beneath.
*/
.tg-16__stroked {
  font-size: clamp(1.6rem, 5vw, 2.8rem);
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.1;
  background: linear-gradient(90deg, var(--g-a) 0%, var(--g-b) 50%, var(--g-c) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  -webkit-text-stroke: 1px rgba(232,121,249,.45);
  display: block;
  margin-bottom: 32px;
}

.tg-16__grid {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: 28px;
}
.tg-16__example {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.tg-16__ex-lbl {
  font-size: .7rem;
  color: var(--muted);
  letter-spacing: .06em;
}

.tg-16__stroke-only {
  font-size: 3rem;
  font-weight: 900;
  -webkit-text-stroke: 2px var(--g-a);
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.tg-16__fill-only {
  font-size: 3rem;
  font-weight: 900;
  background: linear-gradient(90deg, var(--g-b), var(--g-c));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.tg-16__both {
  font-size: 3rem;
  font-weight: 900;
  background: linear-gradient(90deg, var(--g-a), var(--g-b), var(--g-c));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  -webkit-text-stroke: 1.5px rgba(255,255,255,.35);
}

.tg-16__note {
  font-size: .8rem;
  color: var(--muted);
  line-height: 1.65;
}
.tg-16__note code {
  background: rgba(255,255,255,.07);
  border-radius: 3px;
  padding: 1px 5px;
  color: var(--g-a);
  font-size: .78em;
}

@media (prefers-reduced-motion: reduce) {}

How this works

The -webkit-text-stroke shorthand sets stroke width and colour simultaneously. When combined with background-clip: text gradient fill and -webkit-text-fill-color: transparent, the stroke paints on top of the gradient fill as a second layer. The paint-order: stroke fill CSS property (supported in modern browsers) controls whether the stroke appears under or over the fill, preventing stroke from obscuring thin letterform detail.

For the stroke-only pattern, -webkit-text-fill-color: transparent is set without a background gradient, so only the stroke outline renders — ideal for oversized display type or outlines over photographic backgrounds. Semi-transparent stroke colours (rgba(…,.35)) are recommended when layering over gradient fills so the underlying colour shows through, creating depth rather than a harsh border.

Customize

  • Adjust stroke width from 2px to 4px on -webkit-text-stroke for headline display sizes above 6rem where thin strokes become invisible at a distance.
  • Change the stroke colour's alpha from .35 to .8 for a bolder outline that contrasts with the gradient fill — works well on light backgrounds where the gradient has low contrast.
  • Combine outline text with a backdrop element: place the stroked word behind a solid filled version via position: absolute and a slight offset for a drop-shadow-like 3D effect.
  • Use -webkit-text-stroke: 1px white with a dark gradient fill on light backgrounds to create a crisp white outline that separates the word from both the page colour and the gradient.
  • Add a filter: drop-shadow(2px 2px 0 rgba(var(--g-a-rgb), .4)) alongside the stroke for a hard-edge geometric shadow that reinforces the outlined letterform.

Watch out for

  • -webkit-text-stroke grows inward and outward equally from the glyph edge. At large stroke widths (>3px on display text) it will noticeably thin the counters of letters like 'e', 'a', and 'B'. Use stroke widths ≤2px at sizes below 80px to preserve legibility.
  • paint-order: stroke fill requires Chrome 62+ and Firefox 60+. In older browsers the stroke paints over the fill, obscuring the gradient inside heavy letterforms. Include the property as a progressive enhancement only.
  • Combining -webkit-text-stroke with background-clip: text and filter: drop-shadow() simultaneously can cause Safari to rasterise the element incorrectly — test this combination on Safari and remove the filter if artefacts appear.

Browser support

ChromeSafariFirefoxEdge
62+ 10.1+ 60+ 62+

paint-order: stroke fill requires Chrome 62+ and Firefox 60+; older browsers paint stroke over fill which obscures gradient fill at wide stroke widths.

Search CodeFronts

Loading…