0

I'm embedding SVG definitions for common icons we're using throughout our site:

<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0" display="none">
  <symbol id="icon-1" viewbox="0 0 113.8 113.8">
    <title>Icon 1</title>
    <g>
      <circle class="st2 outter-circle" cx="56.9" cy="56.8" r="55" />
      <line class="st1" x1="56.9" y1="71.5" x2="56.9" y2="86.3" />
    </g>
  </symbol>
</svg>

(Truncated that for this example.)

Then I'm including it in my markup as:

<svg viewBox="0 0 100 100" class="campus-icon white five-eighths">
    <use xlink:href="#icon-1"></use>
</svg>

The problem I'm running into is choosing a color scheme for the icon by setting a class for the SVG object.

These are the default styles:

.st1 {
    fill:none;
    stroke:#363636;
    stroke-width:0.75;
    stroke-linecap:round;
    stroke-linejoin:round;
    stroke-miterlimit:10;
}

.st2 {
    fill:none;
    stroke:#363636;
    stroke-width:2;
    stroke-miterlimit:10;
}

What I tried doing is allowing the class on the SVG object help define the stroke color of the icon:

.campus-icon.white .st1,
.campus-icon.white .st2 {
  stroke: #FFF;
}

This seems to work in Firefox, but not in Chrome or Safari.

Because my icons have two colors, this is something I really need to figure out (if it's even possible).

From what I can tell Safari and Chrome won't allow me to use a selector on the SVG object followed by a selector within the SVG itself.

To test this theory, I took this working example (SVG CSS Hover Styling) and created a CodePen instance (http://codepen.io/ericrovtar/pen/ZeZqRE).

Anyone know if there is a way to accomplish this?

Thanks!

-Eric

Community
  • 1
  • 1
Eric R
  • 673
  • 2
  • 9
  • 15
  • Just to clear it up, you need `.st1` and `.st2` to have different stroke colors? – ccprog Apr 05 '17 at 16:19
  • Essentially, AFAIK, you can't target sub-parts of an SVG with CSS in a `use`. It''s like trying to target an area of an image. FF might support it but webkit/blink does not. – Paulie_D Apr 05 '17 at 16:27
  • Firefox is buggy in this regard, if we ever fix this bug Firefox will work as webkit/blink does. If you want to content differently do not use . is for displaying a single piece of content identically. Instead you should clone the original using javascript and manipulate the clone as you see fit. – Robert Longson Apr 05 '17 at 16:43
  • Thanks, everyone! I figured it was non-standard. As I read about this before posting, I saw similar issues. I hope they work to resolve this somehow because this limits some of the capabilities of SVGs. Sure, there are still plenty of reasons they're great, but this would make them much more useful throughout a full site. – Eric R Apr 05 '17 at 17:25

1 Answers1

1

Unfortunately, the Firefox behavior is the non-standard-conformant one. The components of the referenced elements are supposed to sit inside a shadow DOM with a separate CSS parse tree.

But there is a minor loophole: elements in the shadow tree inherit styles from its host <use> element.

A - If you are able to formulate your icons in a way that one color is always applied to a stroke, and the other to a fill, you could leave off defining these colors for the symbols, and only set them for the classes of the use elements.

.st1 {
    fill:none;
    stroke-width:0.75;
    stroke-linecap:round;
    stroke-linejoin:round;
    stroke-miterlimit:10;
}

.st2 { /* the element beeing a rectangle instead of a line */
    stroke:none;
}

.campus-icon.white {
   stroke: #FFF; /* could apply to .st1 */
   fill: #DDD;   /* could apply to .st2 */
}

B - For more complex cases you would need to break up your icons in identically-colored parts and reference these individually, i. e.

<svg viewBox="0 0 100 100" class="campus-icon white five-eighths">
    <use class="part-1" xlink:href="#icon-1-part-1"></use>
    <use class="part-2" xlink:href="#icon-1-part-2"></use>
</svg>
ccprog
  • 20,308
  • 4
  • 27
  • 44