Improved CSS Text-Stroke

Published on

Historically, applying an outer stroke to text via CSS has been tricky.

All major browsers have long supported these (stubbornly vendor-prefixed) properties:

But these always center-align the outline, intruding on text therein. For anything more than a hairline stroke on some decently heavy type, things get real ugly real fast:

Bleh!
The thick stroke rests atop the letterforms, significantly impeding legibility.
Language: CSS
.example {
  -webkit-text-stroke: 0.125em white;
}

(It’s even worse with variable fonts, as documented in this Mona Sans issue and on Stack Overflow.)

Web designers are tenacious, so of course they found workarounds:

Most of the time, though, I just avoided the effect in my work unless it was a key design detail.

But while I wasn’t looking, things improved!

Just the other day, my TTF collaborator Scott Kellum pointed out to me that the paint-order property, available for quite a while in WebKit (Safari) and Gecko (Firefox), gained Chromium support in 2024!

Which means we can now explicitly position the text stroke beneath the text fill, preventing it from crowding out the letterforms:

Neat!
With paint-order applied, the text remains legible atop the stroke.
Language: CSS
.example {
  paint-order: stroke fill;
  -webkit-text-stroke: 0.125em white;
}

As of this writing, there’s still room for improvement:

But I thought I’d share in case this flew under anyone else’s radar.