Here’s a weird thing I learned about styling inline SVG icons with CSS today.
If you apply a stroke
attribute with CSS to an SVG, you might get more than you bargained for.
On my current project, we’re using an inline icon system, and being a responsible developer, I wanted to keep file sizes as small as possible, so I was using SVGO to strip out all the unnecessary garbage that gets added by design programs. I also did a find and replace to swap inline colour values for currentColor
, so that it would be easier to re-use the icons in different contexts.
I compared the before and after icons in my pull request, and everything looked fine, but when they were being used in the page, some of the icons looked strange. One of them ended up with a line around it, and some of them were just a bit odd - the only word I can think of is “blobby” - see for yourself in the Codepen below.
See the Pen SVG by malcomio (@malcomio) on CodePen.
The difficulty of describing the problem made it difficult to Google, and as usual, I went down a long and tedious rabbit-hole of trying to figure out the problem.
I wondered if perhaps the SVGO options I’d used weren’t right, or if 7 decimal points of precision might not be enough. The icons in this project are more complex than the flat icons I’d used in the past, and I spent far too long looking at the text diff of the SVG files, and manually restoring the previous version of the paths or polylines.
The fact that the individual SVGs still looked fine suggested that I might have some problem in the build pipeline - maybe svgstore was configured wrongly. So I spent a long time eyeballing the <symbol>
elements in the combined file, and comparing them with the individual files - everything seemed fine.
After a lot of trial and error, eventually I stumbled upon the answer - just as I had done before, I was setting stroke: currentColor;
on the icons with CSS, based on a mangled version of something I’d read on CSS Tricks. One thing I hadn’t realised is that this affects all the elements, even things like <g>
which aren’t visible, and hadn’t been until SVGO was stripping out the apparently useless stroke="none"
attributes on those elements.
As with so many development problems, a long time investigating has led me to a one-line fix. I’m never quite sure whether or not I like that feeling - somehow those hours of tearing my hear out should be represented by a bigger change than just one line of code (and a deletion at that). On the other hand, there’s a certain satisfying elegance to a simple fix like that.
I’m writing this partly to remind me about this for my next project, and partly to help other people who might be banging their heads against the wall with the same problem. After all, nobody wants things to be blobby.