SVG fill with use tag

Viewed 5209

I'm trying to change the color of an SVG displayed on different pages using <svg id="logo-svg"><use xlink:href="#kmc-logo"></use></svg>.

The methods I'm trying are here: https://tympanus.net/codrops/2015/07/16/styling-svg-use-content-css/.

This is the SVG symbol I'm pulling in (shortened to relevant pieces):

<svg xmlns="http://www.w3.org/2000/svg">
    <symbol id="kmc-logo" viewBox="0 0 151 151">
        <g id="logo">
            <g id="outer-circle">
                <path fill="none" stroke-linecap="round" stroke-linejoin="round" d="M11.51 ..."/>
            </g>
            <g id="ceramics">
                <path stroke="none" d="M39.47 ..."/>
            </g>
        </g>
    </symbol>
</svg>

I have this style in my stylesheet:

#masthead > .content-width .site-branding .logo--white a #logo-svg {
    fill: #fff;
    stroke: #fff;
}

The stroke color here is working fine for the #outer-circle in the shadow-dom'd SVG above, but the fill isn't working on the path inside #ceramics.

Can anyone shed some light? Thanks in advance!

EDIT: I've updated this question after discovering that the issue isn't with css specificity, but rather with styling elements inside shadow-dom svgs.

2 Answers

What you've done seems okay. I've reproduced it roughly below. Perhaps this will help you.

If your "ceramics" path is not showing, then there might be something wrong with it. But we would need to see it.

body {
  background-color: blue;
}

.logo--white #logo-svg {
    fill: #fff;
    stroke: #fff;
}

.logo--yellow #logo-svg {
    fill: #ff0;
    stroke: #ff0;
}

div {
  width: 100px;
  height: 100px;
  margin: 20px;
}
<svg width="0" height="0">
  <symbol id="kmc-logo" viewBox="0 0 151 151">
    <g id="logo">
      <g id="outer-circle">
        <path fill="none" stroke-linecap="round" stroke-linejoin="round"
              stroke-width="10" 
              d="M 25,25 L 25,125"/>
      </g>
      <g id="ceramics">
        <path stroke="none"
              d="M 100,25 A 50,50 0 0 0 100,125 A 50,50 0 0 0 100,25 Z"/>
      </g>
    </g>
  </symbol>
</svg>

<div class="logo--white" viewBox="0 0 151 151">
  <svg id="logo-svg"><use xlink:href="#kmc-logo"></use></svg>
</div>

<div class="logo--yellow" viewBox="0 0 151 151">
  <svg id="logo-svg"><use xlink:href="#kmc-logo"></use></svg>
</div>

In fact, the solution is very simple for you. Just change everywhere in the svg file from fill = "none" to fill = "currentColor". In this case, all the fill properties inside the svg element inherit the color from the parent element that wraps it. Then add color property to parent element.

.logo-svg {
    color: #fff;
}

.logo-svg--yellow {
    color: yellow;
}
<svg class="logo-svg">
  <use href="#some-svg" xlink:href="#some-svg" />
</svg>

<svg class="logo-svg--yellow">
  <use href="#some-svg" xlink:href="#some-svg" />
</svg>

<svg id="some-svg" width="100" height="100">
  <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="currentColor" />
</svg>

Thanks to your question and answer above, I solved my problem by making the changes I described.

UPD. According to the new rules,

instead of xlink:href you should use href

Related