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.
Either the documentation needs to get updated, or vector-effect
’s intended use needs to become more robust.