/color-svg-sprite

A technique for coloring external .svg files using external .css files.

Primary LanguageHTML

Colored SVG Sprite

A technique for coloring external .svg files using external .css files.

Why?

Traditionally, the only way to style an SVG was either inline <svg> tag, or inline css (inside a .svg file).

There is now a new way

method CSS Interactions (e.g. :hover) CSS Animations SVG Animations (SMIL)
<img> No Yes only if inside <svg> Yes
CSS background image No Yes only if inside <svg> Yes
<object> Yes only if inside <svg> Yes only if inside <svg> Yes
<iframe> Yes only if inside <svg> Yes only if inside <svg> Yes
<embed> Yes only if inside <svg> Yes only if inside <svg> Yes
<svg> (inline) Yes Yes Yes
<svg><use xlink:href="sprite.svg"></use></svg> Yes Yes ?

The last way is supported by all browsers (including IE + Edge with a tiny shim). Read on for more!

What?

This repo showcases 2 separate but complimentary points:

  1. Using external SVGs
  2. Styling those SVGs with CSS

Using external SVGs

See svg4everybody for more details.

Given an external file sprite.svg:

<svg xmlns="http://www.w3.org/2000/svg">
  <symbol id="camera" viewBox="0 0 512 512">
    <!-- ... -->
  </symbol>
  <symbol id="pencil" viewBox="0 0 512 512">
    <!-- ... -->
  </symbol>
</svg>

We can load that into our page like so:

<svg>
  <use xlink:href="sprite.svg#pencil"></use>
</svg>

A couple of points to note here:

  • Use of <symbol> instead of <g> inside the svg allows setting the viewBox property, as well as title for accessibility.
  • The xlink:href attribute points to the id of the <symbol> you'd like to use (in this example, we point at the pencil).

With the svg4everybody shim, this works in all browsers.

Styling those SVGs with CSS

Now, we can set a class on the containing <svg> element in the html, and target that with an external stylesheet:

<svg class="color-svg">
  <use xlink:href="sprite.svg#pencil"></use>
</svg>
.color-svg {
  width: 150px;
  height: 150px;
}

Color

Our #pencil svg looks like this:

<symbol id="pencil" viewBox="0 0 512 512">
  <rect x="0" y="0" width="512" height="512" rx="30" ry="30"/>
  <path fill="currentColor" d="..."/>
</symbol>

To change the color of the <rect>, we make use of the fill property:

.color-svg {
  width: 150px;
  height: 150px;
  fill: black;
}

Notice too that the <path> has set fill="currentColor". This is a neat css trick which tells the <path> to inherit the color from its nearest parent that has defined a color style:

.color-svg {
  width: 150px;
  height: 150px;
  fill: black;
  color: #fff;
}

So now, our <path> is colored #fff, and the <rect> is colored black :D

Try the demo, and hover + click to see different color combos.