ben tedder : code issues

Building responsive SVGs with viewBox

There's a fairly easy way to scale SVGs, although it's only easy once you understand it. Lame. So here's my explanation. Hopefully it helps!

Scenario: You have a layered SVG file where the positions of the items needs to stay consistent no matter the browser width.

Example: An svg map with a pin and line marking specific points

I'm going to assume if you're researching svg responsiveness your browser is modern and you can see the svg above. Go ahead and resize your browser window and check it out. The map and its dot and line stay in place. Here's the code (if you haven't already checked it out in the dev tools). Play around with the width and height of the svg element on this page and see how the scaling works for yourself.

<svg width="100%" height="300" viewBox="0 0 500 300">
  <image xlink:href="/images/china-outline.svg" width="100%" height="100%"/>
  <circle cx="330" cy="130" fill="yellow" stroke="black" stroke-width="2" r="5"/>
  <rect x="330" y="150" fill="yellow" height="80" width="1"/>
</svg>

Now here's the same code without viewBox. Resize your window and check out the difference.

<svg width="100%" height="300">
  <image xlink:href="/images/china-outline.svg" width="100%" height="100%"/>
  <circle cx="330" cy="130" fill="yellow" stroke="black" stroke-width="2" r="5"/>
  <rect x="330" y="150" fill="yellow" height="80" width="1"/>
</svg>

As you can see, everything just remains in its relative position to the bounding svg. That's not what we're looking for.

So, basically setting viewBox allows us to build a canvas to work on, and then make that relative to the width of the containing svg. So we don't have to worry about sizing or positioning our elements in relation to the svg, just to the viewBox.

This took me entirely too long to figure out, so hopefully this saves you a lot of time!