Home > Back-end >  Control SVG stroke and fill attributes when referencing through img tag
Control SVG stroke and fill attributes when referencing through img tag

Time:12-25

I downloaded some svgs from bootstrap and added them to my project. Here is an example of person-fill.svg:

<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"  viewBox="0 0 16 16">
  <path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0Zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4Zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10Z"/>
</svg>

If I place this content directly into html, I can manipulate colors through fill and stroke properties.

However, in order to reuse this svg, I added it to my project as svg file, and then I reference it in html through img tag:

<img  src="/images/svg/person-fill.svg" title="User profile" />

This works, however, now I am unable to change colors. Basically, I could change the background color by setting background-color attribute on user-icon class, since this svg is transparent, but I am unable to truly set the fill and stroke attributes.

Anyone knows if its possible to control svg's fill and stroke attributes (preferentially through css class), without the need to copy svg content directly to html? If not, is there some other way where I do not need to copy svg everywhere I use it?

CodePudding user response:

It takes a bit of 'getting the hang of it'. I created a HTML/CSS commented example using your SVG.

But, most importantly, answering your question: you cannot access SVG CSS properties when using it as an <img>, because the browser will treat it as a graphics element and no longer as a XML document. To be able to access those properties you will need to use the svg/use structure described.

The basics:

  • Define a main in-doc SVG

  • Which contains a list (<defs>) of <symbol>, each with a unique id

  • Reference a specific SVG somewhere inside a parent element as you would use an <img>:

    <div >
       <svg>
          <use href="#some-ID">
       </svg>
    </div>
    
  • Edit modifiable SVG properties inside your regular CSS, like fill, stroke, etc.

  • You can even create a <symbol> that uses a list of nested symbols and use that in your <div>. Nesting can go several levels deep with good planning.

    <symbol id="id-1">...</symbol>
    <symbol id="id-2">...</symbol>
    <symbol id="id-3">...</symbol>
     ...
    <symbol id="id-N">...</symbol>
    
    <symbol id="compound-symbol">
       <use href="id-1" />
       <use href="id-2" />
       <use href="id-3" />
    </symbol>"
    
    <symbol id="nested-symbol">
       <use href="compound-symbol" />
       <use href="id-N" />
    </symbol>
    

Here is some Codepen demo I posted almost 2 years ago: svg-burger-menu-patches.

The snippet clarifies things better:

 /* * { outline: 1px dashed } /* for debugging */

/* An element that 'uses' a predefined, in-doc SVG symbol */
.svg-user {
    stroke: hsl(0deg, 100%, 50%, 0.5); /* transparent red */
    fill  : black;

    width: 50vw; /* online size */
    height: 50vw;

    margin: 0 auto;
}

.svg-user>svg {
    display: block; overflow: hidden;

    width : 100%; /* stretch to fill parent */
    height: 100%;
}
<div >
    <svg>
        <use href="#person-fill"/><!-- use the symbol by referencing its ID -->
    </svg>
</div>

<!-- Remove color, size and other attributes from the main <svg> and hide it from view -->
<svg xmlns="http://www.w3.org/2000/svg" style="display: none">
    <!--
        - Move all SVGs you want to use in your page inside <defs></defs> as <symbol>
        - Define a viewbox per <symbol>
        - Give the symbol an ID that can be <use>d
        - Remove attributes you want to control from CSS, except x,y,r, etc.
        - Use (CSS) classes where required
        - A <style> block inside this main SVG will work as expected too
        - As would <script>
        - After all, it is an XML file...
    -->
    <defs>
        <!-- A list of various SVG symbols, each with their own unique ID -->
        <symbol id="person-fill"  viewBox="0 0 16 16">
            <path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0Zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4Zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10Z"/>
        </symbol>

    </defs>
</svg>

CodePudding user response:

You can either open the file to any text editor and change it to any color before uploading to server or call it on css like this. Not sure how many times are you going to use this but this is 2 ways you can do it.

svg {fill: red; }
<svg  xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"  viewBox="0 0 16 16">
  <path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0Zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4Zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10Z"/>
</svg>

  • Related