SVG file that inherits the current color

2

Using SVG inline I can make the current color inherit using the value currentColor for property fill . In this way I can make my image adapt to the color of the element that contains it. For example:

.rojo {
  color:red;
}

.verde {
  color:green;
}
<div class="rojo">
  <svg width="10" height="10" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
    <g id="dibujo">
      <circle cx="5" cy="5" r="4" fill="currentColor" />
    </g>
  </svg>
  Hola
</div>
<div class="verde">
  <svg width="10" height="10" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
    <g id="dibujo">
      <circle cx="5" cy="5" r="4" fill="currentColor" />
    </g>
  </svg>
  Adiós
</div>

That's great because it works: the circles look different in color even when the code for the SVGs is the same in both cases. The problem is that I do not want to have the same inline code many times.

I'd prefer it to be in an external file, like this one that I'll call my Image-svg:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="10" height="10" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
    <g id="dibujo">
        <circle cx="5" cy="5" r="4" fill="currentColor" />
    </g>
</svg>

and then you can easily add it multiple times:

<div class="rojo">
  <img src="./miImagen.svg" alt="Mi SVG en rojo" />
  Hola
</div>
<div class="verde">
  <img src="./miImagen.svg" alt="Mi SVG en verde" />
  Adiós
</div>

But if I do that, currentColor stops working and you see the circles in black (I add capture of the result because it does not allow me to upload SVG):

How can I do to include an "external" SVG and inherit the value of currentColor ?

  

Note: the image I'm going to work with is bigger and more complex than just a circle that changes color, it would have multiple colors and lines that would change color with currentColor . I had planned to put it in a font and include it as the glyphicons of Bootstrap or FontAwesome, but being large and multicolored, I do not know if that option is feasible.

    
asked by Alvaro Montoro 22.11.2016 в 18:45
source

2 answers

3

I found a possible solution that, instead of using the img tag, uses the tag use within a svg inline and that works as I want.

What the use tag does is that it takes the nodes from within an SVG and duplicates them where the tag is. Basically it is like cloning the content of the linked SVG within the SVG that links it with use . And the best thing is that it seems to work in Chrome, IE and Firefox without problems.

Starting with an SVG image that I created (which I will call myImage.svg):

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="10" height="10" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
    <g id="dibujo">
        <circle cx="5" cy="5" r="4" fill="currentColor" />
    </g>
</svg>

What I would do is create a svg inline tag, that includes (use) the group with id #dibujo of myImage.svg:

<svg>
  <use xlink:href="miImagen.svg#dibujo"></use>
</svg>

When using use , it's as if the group with id #dibujo within myImage.svg was cloned and was inline in the document, so the CSS styles for the color were Apply thanks to currentColor and it works as I want.

  

One problem is that the file linked with use is subject to certain security rules and both the domain, protocol and port must match the page and the SVG file ... so I can not give an example that work completely here.

But the idea would be this:

.rojo {
  color:red;
}

.verde {
  color:green;
}

svg {
  width:10px;
  height:10px;
}
<div class="rojo">
  <svg><use xlink:href="miImagen.svg#dibujo"></use></svg>
  Icono Rojo
</div>
<div class="verde">
  <svg><use xlink:href="miImagen.svg#dibujo"></use></svg>
  Icono Verde
</div>

It's not as simple as simply using img but it adapts quite well to what I want and it's not overly complex.

One good thing about using use is that it can be used with external and internal resources, that is, with elements that are already on the page. So, another option would be to put my SVG inline once and reference it multiple times (but then I would not take advantage of the browser's cache).

Here is an example:

#circulo-original {
  display:none;
}

.rojo {
  color:red;
}

.verde {
  color:green;
}

.circulo {
  width:10px;
  height:10px;
}
<!-- mi SVG original, inline y oculto -->
<svg id="circulo-original" width="10" height="10" viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
  <g id="dibujo">
    <circle cx="5" cy="5" r="4" fill="currentColor" />
  </g>
</svg>

<div class="rojo">
  <svg class="circulo"><use xlink:href="#dibujo"></use></svg>
  Icono Rojo
</div>

<div class="verde">
  <svg class="circulo"><use xlink:href="#dibujo"></use></svg>
  Icono Verde
</div>

Some links that helped me with this solution:

answered by 23.11.2016 / 01:30
source
1

I will not give you the exact answer you ask because I sincerely believe that you can not, but maybe this will help you. I have taken the following as the most important elements:

  • The svg file must be external
  • I should be able to change the color of different svg elements
  • The color of the element that contains it must be inherited
  • If you use the first two, keep reading:

    The svg file must be modified to add a stylesheet by putting the following before the svg tag:

    <?xml-stylesheet type="text/css" href="estilo.css" ?>
    

    Also, if as in the case that you propose at the end it is going to be a "complex" svg (but not much to not die putting labels) and you want to apply the color change only to some parts you must put an attribute class to each path that you want to modify by CSS.

    Once this has been done the way to change the color will be through the stylesheet , not by inheritance:

    .pathPrueba1 {
        fill: red;
    }
    

    And finally to insert it in your HTML you must add it as a object :

    <object type="image/svg+xml" data="mi.svg"></object>
    

    It does not matter which CSS you apply to HTML, the style is being given the reference you have in the SVG file. If you want to apply style in HTML you will have to paste the contents of the svg inside, being able to apply styles freely to each part as you have already done.

    All this I have removed from the following link: link

    There is some other trick, maybe you can find a solution that suits more exactly what you want (includes example with blurs and other things).

        
    answered by 22.11.2016 в 22:31