Published at
Updated at
Reading time
2min
This post is part of my Today I learned series in which I share all my web development learnings.

Dealing with SVGs can be fiddly at times. Sometimes you only want to adjust the stroke of a rect to discover that it changes the visual appearance in an unexpected way.

Define an element's stroke-width in CSS or a presentation attribute in markup.

path {
  stroke-width: 3;
}
<path stroke-width="3"></path>

If you increase the stroke width by more than a few pixels, you'll see that the stroke width will change to both sides - to the inside and outside.

In this case, I usually changed the path or width/height of the given element to avoid the stroke going over the filled area too much. But it turns out that you can change the paint order of fill and stroke using paint-order.

The default order is described via the normal value, and it defines that fill will be painted first, then the stroke, and finally the markers. But you can redefine the paint order so that the stroke is not painted over the fill area with stroke fill markers.

If you omit any of the three painting components, they will be painted in their default order after the specified components.

path {
  /* 
   * paint order: fill, stroke, markers 
   *
   * Stroke is painted above fill.
   */
  paint-order: normal;
  
  /* 
   * paint order: stroke, fill, markers
   *
   * Stroke is painted below fill.
   */
  paint-order: stroke fill markers;
  
  /* 
   * shorthand 
   * 
   * paint order: stroke, fill, markers
   */
  paint-order: stroke;
}
<!-- paint order: fill, stroke, markers -->
<path stroke-width="3" paint-order="normal"></path>
<!-- paint order: stroke, fill, markers -->
<path stroke-width="3" paint-order="stroke fill markers"></path>
<!-- paint order: stroke, fill, markers -->
<path stroke-width="3" paint-order="stroke"></path>

This way, the stroke is painted first, followed by the fill color. You can then expand the stroke width as much as you want, and it will look like it's expanding only to the outside because the fill color will be on top of the stroke. ๐ŸŽ‰

That's a handy trick!

Visualisation showing the effect of paint-order

If you want to learn more about this, check the MDN article or play around with it on CodePen.

paint-order works in CSS, too!

But guess what? Adam Argyle shared that paint-order works for "regular CSS", too.

When you check MDN, you'll discover that there's paint-order(SVG) and paint-order(CSS).

When would this work in CSS land? If you apply -webkit-text-stroke (despite the -webkit prefix, it's supported in all engines), you can control if the "text fill color" set via color is painted above or below the applied stroke.

Play with the controls to see the effect... ๐Ÿ‘‡

.headline {
  -webkit-text-stroke: 5px blue;
  paint-order: stroke fill;
}
Huzzah!

Wild!

If you enjoyed this article...

Join 5.5k readers and learn something new every week with Web Weekly.

Web Weekly โ€” Your friendly Web Dev newsletter
Reply to this post and share your thoughts via good old email.
Stefan standing in the park in front of a green background

About Stefan Judis

Frontend nerd with over ten years of experience, freelance dev, "Today I Learned" blogger, conference speaker, and Open Source maintainer.

Related Topics

Related Articles