Crispy dashed borders

Tags
  • design
  • dashed
  • stroke
  • svg
Publish date
Read time 3 min read

So, you want to draw a perfectly even dashed border around your HTML element? At first glance, it looks like a no-brainer. However, I soon realized there are nuances.

This is the design: we want a pixel-perfect, evenly distributed dashed border around an image.

A space invader alien within a dashed rectangle
A space invader alien within a dashed rectangle

Navigate to "Basic solution" Basic solution

Okay, you say. Let’s slap on some CSS border-style on it. Right? Well, check what happens when i do.

300x300
The CSS-only version. The dashes are ugly near the corners

Check the dashes around the corners. They are congested. Drawing dashes evenly works much nicer when using an SVG instead. Check the following example.

300x300 />
SVG version. Check the even dashes near the corners

Much better, isn’t it? We are using an almost full-sized <rect> with some stroke-dasharray pattern. And look at that, it already prettier.

Navigate to "Further improvements" Further improvements

So there are more things that bothers me:

Navigate to "Overflow" Overflow

Why is that? Well, in SVG, strokes are naturally centered on the shape’s path. Anything that overflows is hidden because of how HTML works: images generally don’t spill beyond their bounds.

There are clever techniques that rely on techniques that rely on <clip-path> or <mask> while shrinking the original object, but I found the most elegant solution from Josh Comeau: overflow: visible ✨. We allow the spillover: overflow: visible ✨. We simply allow the spillover.

Navigate to "Scaling" Scaling

Perfect, but we can make it even better.

By default, when we scale (stretch or squish) an SVG, the strokes are affected by vector transformations. We can opt out if we use preserveAspectRatio on the SVG itself, but what if that’s not an option?

We can use a ‘hidden’ SVG feature called vector-effect: non-scaling-stroke. Rich Harris has a great article on applying this to data visualization. With this property, the stroke width remains independent of the transformation. It also affects the dash pattern, making it render even more cleanly. The browser calculates the stroke width based on the screen pixels rather than the internal SVG coordinate system

To be honest, it’s an optional property that depends on the final design requirements. Check out the following example and experiment with different sizes or zoom levels!

Final solution. Resize the element to scale
Back to top