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.

Comments

  1. User Avatar
    Herman

    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.

    • User Avatar
      Chris Coyier

      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.

Submit a Comment

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

icon-anchoricon-closeicon-emailicon-linkicon-logo-staricon-menuicon-nav-guideicon-searchicon-staricon-tag