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
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
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
- 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”.