Inline SVG can be “styled” in the sense that it already has fills and strokes and whatnot the second you put it on the page. That’s awesome and a totally fine way to use inline SVG. But you can also style inline SVG through CSS, which is kinda awesome because, I imagine for a lot of us, CSS is where we feel powerful and comfortable.
It works pretty much how you would expect. Here’s a simple example:
<svg>
<rect class="my-rect" ... />
</svg>
.my-rect {
fill: blue; /* remember it's fill not background, teamsters */
}
CSS has a bit “more power”, you could say, than style attributes on the SVG elements themselves. If that <rect>
had like fill="red"
on it, the CSS would still “win”. You might think the opposite because it seems like style attributes would be powerful like inline styles, but they aren’t. Inline styles are still powerful though.
Likewise, CSS rules don’t cascade down if there is anything at all more specific happening. For instance:
<g class="parent">
<rect fill="blue" />
</g>
.parent {
fill: red;
}
The CSS loses in this case, because the blue is being applied more specifically to the rect.
If I’m planning to style SVG through CSS, I generally find it easiest to just leave style attributes off the SVG elements entirely.
Important thing to know alert!
We’ve spent time talking about <use>
. Say this is the situation:
<svg>
<symbol viewport="0 0 100 100" id="thing">
<rect class="child" ... />
<symbol>
</svg>
<svg class="parent">
<use xlink:href="#thing" />
</svg>
Ultimately that “child” gets put in that “parent” right? Right. So this should work?
.parent .child {
fill: red;
}
But it does not.
That the way <use>
works, it clones that <symbol>
and puts it into a “Shadow DOM” in that second SVG. You can’t penetrate through that shadow DOM with a selector like that. Just doesn’t work. Perhaps someday there will be a solution, but there isn’t right now.
You can do like:
.parent {
fill: red;
}
And that fill will cascade through and affect the child elements if there is nothing more specific in the way. Or
.child {
fill: red;
}
and affect all instances of that child. But just not both.
If you do need differently styled versions of the same thing…
Just duplicate the <symbol>
or whatever you need. The vast majority of the information will be identical, and GZip eat identical text for breakfast.
A gotcha I just discovered when defining your SVGs in an external file is that you cannot have
<style>
tags inside a<symbol>
– the styles will not apply when doing a<use xlink:href="stuff.svg#mysvg"></use>
. For instance this icon from Polymer is using CSS styling, as opposed to presentational attributes.To solve that, you can convert the SVG to use only presentational attributes for styling. In Illustrator just save it and in the dialog, select “Presentational Attributes” under Advanced Options > CSS Properties.
Yeah there is a fundamental difference there. When referenced externally, it doesn’t share the same DOM as the rest of the document like it does when you
use
from the same document.I would be very happy to know if anything was renewed and there is a possibility to write a css design to a specific class in the svg file!
thank you:)
Hey there! Yes, you can absolutely create a classname in the inlined SVG and call that class in a stylesheet. The trick is make sure that the properties you want to control in the CSS are not already set in the SVG itself because, just like CSS, inlined properties will supersede stylesheet properties.
It is now possible to style individual components of symbols differently on use by using CSS custom properties.
Example: