Sketch’s Brilliant New Way to Export Borders as SVG

Sketch just released version 43, and there’s one improvement that is so noteworthy I need shout from the rooftops with joy.

It has to do with exporting SVGs.

SVG is a brilliant and capable graphics format, but it has yet to support inside or outside borders.

As a result, every design software that exports SVG has to solve this problem:

If your design uses inside or outside borders, how can those layers be recreated in an identical yet SVG-friendly way?

There have been 3 main approaches:

  1. Outline the borders: turn them into filled-in shapes rather than lines.
  2. Switch to centered borders, but create a mask to hide the inner or outer half.
  3. Switch to centered borders, then manually reposition the points in the path yourself (easy for basic shapes, time-consuming for curved or combined shapes).

Option 1 produces a reliably identical SVG, but has a few drawbacks, such as a larger file size. More about these drawbacks in the “Side Note” below.

Option 2 increases both the complexity and file size of an SVG, and is prone to breaking (not reliably looking identical to your design).

Option 3 produces clean SVGs, small file sizes, and reliably identical results. Although this is clearly the best option, it can be time consuming to manually recreate non-basic shapes before exporting (as shown below).

Option 3: Recreating an inside/outside border identically—but with a centered border—often requires moving each vector point, which is laborious for complex shapes.

Before we go any further, it’s important to note that SVG uses the term stroke instead of border. They’re effectively the same thing, but I try to use border when talking about Sketch (i.e. a layer before it has been exported) and stroke when talking about SVG (the exported result).

Which options do different design tools use?

Adobe Illustrator outlines inside/outside borders during SVG export, Figma uses a perplexing combination of outlining and masking, Affinity Designer uses outlining, and — before version 43 — Sketch used masking.

Here’s the big news:

Sketch now does Option 3 for you automatically during SVG export.

Starting with version 43, Sketch reconstructs the layer and its border to be perfectly identical while using centered SVG strokes.

No other design software does this, and it has made Sketch’s SVGs far more reliable and smaller in file size.

I’ve been beta-testing Sketch 43 for the past few weeks, exporting tons of SVGs, and this new feature has been working well. In one design I noticed a rare bug, where a recreated SVG path from an outside border had an extra vector point — but that was easy to work around and the Sketch team is aware of the bug.

💡 Side Note: I’m always surprised by how many people promote the idea that SVGs shouldn’t have strokes — that they should always be outlined, as described above in Option 1. As an all-encompassing statement, that’s simply not true. Certain programs that accept SVGs may require this, but outlining borders has drawbacks: most notably, it increases file size and prevents you from changing stroke-width later on. Furthermore, outlined borders (<path> elements) have the exact same browser support as SVG strokes, and outlining is not required to use CSS to change the color of an icon. I discuss this more in my new Sketch & SVG course.

🤓 For SVG Nerds Only…

If you’ve ever opened up an SVG to see or edit its code (or, “markup”), there’s one more thing you should know about Sketch’s new borders feature.

When a layer in Sketch has a border and a fill, the SVG markup changes a bit. Imagine that layer is a light green circle with a green border. If that border is centered, the resulting SVG will place a fill and a stroke attribute on the same <circle> element, as you’d expect. But if the border is inside or outside, the SVG markup changes significantly: Sketch separates the fill and the stroke into separate <circle> elements. Furthermore, the circle responsible for the fill is moved into the <defs> element, and later referenced by a <use> element. Here’s a simplified example:

Fill + Centered Border:
(This is what you’d expect.)

<svg ...>
<circle fill="lightgreen" stroke="green" .../>
<!-- stroke and fill are on the same shape -->
</svg>

Fill + Inside/Outside Border:
(Doesn’t this seem a little excessive?)

<svg ...>
<defs>
<circle id="fill-area" .../> <!-- this is the fill's shape -->
</defs>
<g id="layer-name">
<use fill="lightgreen" xlink:href="#fill-area"/>
<circle stroke="green" .../> <!-- this is the stroke's shape -->
</g>
</svg>

There may be very rare cases when you want separate SVG elements for your fill and border, but those can easily be prepared as 2 layers before export. Most of the time you just want your SVG graphic to look identical to your Sketch design and have the smallest file size possible.

As you can see in the code snippets above, layers with a fill + inside/outside border will always be larger in file size than those with centered borders. But there’s another drawback too: antialiasing artifacts around the shared edge of the border and fill layers.

In other words, the visual appearance of your design actually changes when you separate a stroke/border and a fill into discrete elements. That’s because they have the same edges, and although it would seem air-tight, the background colors seep through when a computer renders the design into pixels to show up on your screen. Quite simply, that makes your icons or graphics look bad.

How to fix this:

If you’re familiar with editing SVG code, the solution is pretty simple: add the fill attribute to the element with a stroke, then delete the fill <use> element and what it referenced in <defs>. The result is identical, but doesn’t have the antialiasing issue, and it uses considerably less code:

<svg ...>
<circle id="layer-name" fill="lightgreen" stroke="green" .../>
<!-- stroke and fill both on the stroke's shape -->
</svg

To be clear, this is a very minor issue and fixing it is completely optional. Your SVG will show up reliably either way. And it’s not technically a bug — I’ve discussed all of this with the Sketch team, and they’ve decided to stick with their approach for now. My suggestions are “an optimization” for people who want perfect visuals and smaller file sizes.

A tool that does this for you!

I’ve created a simple web-app called SVGito that does this fill+border optimization (along with a few other Sketch-related SVG optimizations) automatically for you. Using it is as simple as pasting in your SVG markup, then copying the optimized version!

You can learn more about it, and the optimizations included, in this article.

It’s not intended to replace other SVG optimizers, like Sketch’s SVGO plugin or SVGOMG, but rather to provide you with additional optimizations that you won’t find in those others. SVGito is available now, and yes—it’s free. :)

Sketch 43’s improvements extend beyond this fantastic SVG borders feature, so be sure to check out their article about what’s new.

I also just released my new course, SVG Workflows in Sketch, which inspired this article in the first place. It dives into all of the ways you can prepare your layers to meet SVG’s constraints, the basics of how SVG works under the hood, advanced tricks for working with vector shapes, and how to optimize the SVG you export so that it’s perfectly suited for your project.

Thanks for reading!


Sign up for my newsletter to be the first to know when I publish new design articles and resources.

If you enjoyed this article, you’ll love Sketch Master — my online training courses for professionals learning Sketch. You’ll learn tons of tricks and practical workflows, by designing real-world UI/UX and app icon projects.

Show your support

Clapping shows how much you appreciated Peter Nowell’s story.