Be careful with your viewBox
In Sara Soueidan’s article: SVG Style Inheritance and the ‘Flash of Unstyled SVG’, Sara explains the importance of having width
, height
, and viewBox
attributes on SVG elements. This reminded me of two issues I ran into last week building my new design.
I have an SVG sprite for social icons:
These three icons live within a single file (see Sara’s guide to SVG sprites). To reused an icon is as simple as referencing it like so:
<svg>
<use xlink:href="icons.svg#twitter"></use>
</svg>
With CSS I can style the size and colour of individual icons, amongst other properties. At least that is the basic principle. Of course, when your asset pipeline is a mess of custom node scripts, what’s eventually rendered in the browser can be a delightful surprise.
My icons weren’t displaying at all.
I checked my SVG sprite source and it looked correct:
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="twitter" viewbox="0 0 34 28">
<!-- [path data] -->
</symbol>
<symbol id="github" viewbox="0 0 28 28">
<!-- [path data] -->
</symbol>
<symbol id="codepen" viewbox="0 0 28 28">
<!-- [path data] -->
</symbol>
</svg>
I checked my minified SVG sprite source and it looked suspiciously empty:
<svg xmlns="http://www.w3.org/2000/svg">
</svg>
If you’re using a minifying tool based on SVGO you need to disable a couple of plugins (‘cleanupIDs’ and ‘removeViewBox’). This will ensure the <symbol>
elements are not removed from your sprite.
That fixed, I refreshed to find my icons were now visible but not scaling correctly. Regardless of what CSS width
or height
values I set they refused to listen. After a brief spell of bewilderment I realised that my minified sprite was still missing the viewBox
attributes on each <symbol>
. Browsers will not scale SVG without this attribute.
Why was it being removed? That’s because — and this took me an embarrassingly long time to notice — my viewbox
attributes were lower-case. From testing it seems browsers don’t actually care but SVGO is case-sensitive in this scenario. Not recognising the lower-case viewbox
it was being removed.
I’ve uploaded an example on CodePen to demonstrate:
I suppose I’ve learnt two important lessons here:
- Never remove the
viewBox
- Beware of meddling tools that do!
It’s funny how long front-end problems can take to debug. I sat there comparing my website to a previous one I’d built playing spot-the-difference for the longest time. The solution was no more than a capital “B”.