A forewarning: Unfortunately, I am going to share a roadblock I ran into, rather than a solution. I am sorry if this post is a bit of a downer.
Recently, I was working on a website for a client that included vector images of maps. The maps look something like this. These are vector maps in a line art style, where the maps appear hand drawn.
Here’s an example design with the map, so you can see what I’m working with:

What I wanted to do was place an inline SVG on the page, then scale its size along with the page itself. So I wrote code like this:
svg.map {
display:block;
margin:0;
width:100%;
height:auto;
}
You know, your bog-standard CSS.
This works as expected: the SVG scales along with the width of the page, and the aspect ratio of the SVG never changes. (The aspect ratio in this example is not a known quantity, and the client could change this map at any time to a different location.)
Here’s the problem: as the SVG scales, the strokes in the SVG scale as well. On a phone, the map looks correct: 1px strokes surrounding each country. On a desktop, it looks ridiculous: the strokes are 20px wide. It’s as if somebody drew the map with a highlighter.
To fix this, I turned to vector-effect
— in particular, non-scaling-stroke
. As always, the MDN Web Docs page is very helpful.
Here’s the problem with non-scaling-stroke
: It only seems to work if you scale the SVG with transform="scale(X,Y)"
. It has no effect if you are merely resizing the SVG with CSS.
So this code does not work:
<style>
svg.map {
display:block;
margin:0;
width:100%;
height:auto;
}
</style>
<svg viewBox="0 0 500 240">
<path
vector-effect="non-scaling-stroke"
d="M10,20 L40,100 L39,200 z"
stroke="black"
stroke-width="2px"
fill="none"></path>
</svg>
Instead, the path
must look like the following:
<path
vector-effect="non-scaling-stroke"
transform="translate(300, 0) scale(4, 1)"
d="M10,20 L40,100 L39,200 z"
stroke="black"
stroke-width="2px"
fill="none">
</path>
This was a huge disappointment for me, and for a few peers I ran this problem by. We all expected my solution to work because nowhere in the documentation does it say that scale
is required.