Firefox and SVG Fill with CSS
As you may have noticed, my site's gone through a bit of a redesign as of late. My portfolio site in particular shows a couple of little ideas I had.
One of those ideas was this pretty little starburst effect on the header with a few abstract shapes coming out of it.
There's a fair bit to it, but it boils down to an SVG sprite sheet and referencing those as svg
elements with use
elements. A bit more versatile than icon fonts, and without the overheads of multiple requests for images. But I digress.
The Issue
This all worked nice enough in the newer browsers until it got to Firefox.
The colours weren't taking hold. Which is a bummer.
The way the colours are determined are fairly simplistic. There's 8 random icons and their colour defaults to orange, with every third one was light blue, and the one after that was navy:
/* "Randomise" the colours, based on the order they come out */
fill: $color-1;
&:nth-of-type(3n) {
fill: $color-2;
}
&:nth-of-type(3n + 1) {
fill: $color-3;
}
It applies fine in the other browsers, just not Firefox. The inspector says they've been applied but they're all still orange.
Frustrating to say the least. But thankfully the solution was a simple one - even if it did require a romp through the Shadow DOM.
The Solution
The SVG sprite is one big SVG with lots of symbol
tags denoting each icon. When Firefox encounters this, it sticks another svg
tag in to display the contents of our symbol
.
It's supposed to treat it as such, but not quite so literally. There's nothing in the inspector that shows it's doing that. It's doing it all internally. There's no problem with doing that, but it just means our selector isn't picking up the shadow version of our icon.
A quick addition to our CSS will cover this situation and make sure it gets picked up by Firefox:
//"Randomise" the colours, based on the order they come out
fill: $color-1;
&:nth-of-type(3n),
&:nth-of-type(3n) use > svg {
fill: $color-2;
}
&:nth-of-type(3n + 1),
&:nth-of-type(3n + 1) use > svg {
fill: $color-3;
}
The use>svg
will pick up the internal svg
tag and fill the contents of that directly. Hey presto! Proper colours again!
As always, Stack Overflow to the rescue! That issue isn't directly related, but the solution remains the same.