skip to Main Content

I’m trying to set a simple css :hover { color changing upon an svg used in background:url()

I’m trying to use stroke="currentColor", but this is not working.

The only possible way seems to be to duplicate the code by just changing the color, but obviously that’s not the most elegant solution.

Did I miss something ?

this is my code:

.sz30 {
  --siz   : 30px;
  display : inline-block;
  width   : var(--siz);
  height  : var(--siz);
  margin  : 1rem;
  background-size : cover;
  cursor          : pointer;
  caret-color     : transparent;
  }

.test_ccGreen {
  color:green;
  background : url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" stroke-width="3" stroke="currentColor"><path d="M4.34 2.93l12.73 12.73-1.41 1.41L2.93 4.35z"/><path d="M17.07 4.34L4.34 17.07l-1.41-1.41L15.66 2.93z"/></svg>');
  }
.test_ccBlue {  
  color:blue;
  background : url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" stroke-width="3"  ><defs>%3Cstyle%3Epath{stroke:currentColor;}%3C/style%3E</defs><path d="M4.34 2.93l12.73 12.73-1.41 1.41L2.93 4.35z"/><path d="M17.07 4.34L4.34 17.07l-1.41-1.41L15.66 2.93z"/></svg>');
}
.test_ccGreen:hover, .test_ccBlue:hover { color:red; } 

.test_duplicateSVG {
  background : url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" stroke-width="3" stroke="rgb(24,97,52)"><path d="M4.34 2.93l12.73 12.73-1.41 1.41L2.93 4.35z"/><path d="M17.07 4.34L4.34 17.07l-1.41-1.41L15.66 2.93z"/></svg>');
}

.test_duplicateSVG:hover {
  background : url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" stroke-width="3" stroke="crimson"><path d="M4.34 2.93l12.73 12.73-1.41 1.41L2.93 4.35z"/><path d="M17.07 4.34L4.34 17.07l-1.41-1.41L15.66 2.93z"/></svg>');
}
<div class="sz30 test_ccGreen"></div>
<div class="sz30 test_ccBlue"></div>

<div class="sz30 test_duplicateSVG"></div>

2

Answers


  1. First of all, background-image:url svg***
    its not svg. its rendering like image.
    so you cant use svg props there. its just image.
    you would use filter method.

    if you wanna use like svg. just paste svg codes in to html, then write css.

    its 2 example for you:

    .sz30 {
      --siz: 30px;
      display: inline-block;
      width: var(--siz);
      height: var(--siz);
      margin: 1rem;
      background-size: cover;
      cursor: pointer;
      caret-color: transparent;
    }
    
    .test_ccGreen {
      color: green;
      background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" stroke-width="3" stroke="currentColor"><path d="M4.34 2.93l12.73 12.73-1.41 1.41L2.93 4.35z"/><path d="M17.07 4.34L4.34 17.07l-1.41-1.41L15.66 2.93z"/></svg>');
    }
    
    .sz30:hover {
      filter: invert(73%) sepia(14%) saturate(666%) hue-rotate(301deg) brightness(108%) contrast(101%);
    }
    
    
    /* 
    filter generator:
    
    */
    
    
    /* css*/
    
    .real-svg svg {
      stroke: pink;
      max-height: 50px;
    }
    
    .real-svg svg:hover {
      stroke: black;
    }
    
    
    /* and for images*/
    <!--oldies-->
    <div class="sz30 test_ccGreen"></div>
    
    <!--goldies-->
    <div class="real-svg">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" stroke-width="3" stroke="crimson"><path d="M4.34 2.93l12.73 12.73-1.41 1.41L2.93 4.35z"/><path d="M17.07 4.34L4.34 17.07l-1.41-1.41L15.66 2.93z"/></svg>
    </div>
    Login or Signup to reply.
  2. I presume your are stuffing SVG in background because you want to prevent style-bleeding, duplicate ID issues, etc. And maybe even SSG.

    I also presume (since you are drawing icons) you are creating UI icons, and not huge SVGs

    It might be easier then to define a native Web Component <svg-icon>
    that creates all SVG client-side;

    With shadowDOM so you get the same encapsulation as an IMG background, but the ability to style it with global CSS (because inheritable styles like color do cascade into shadowDOM)

    Note: (unlike Frameworks) it doesn’t matter when you define the Web Component; all existing or future <svg-icon> elements will automagically be upgraded.
    You can put this code in a <script> in the <head> to prevent FOUCs

    <style>
      svg-icon {
        color: grey;
        --iconhovercolor:green;
        width: 120px;
      }
    </style>
    
    <svg-icon></svg-icon>
    <svg-icon is="plus" style="color:hotpink"></svg-icon>
    <svg-icon is="plus" style="color:blue"></svg-icon>
    
    <script>
      customElements.define('svg-icon', class extends HTMLElement {
        connectedCallback() {
          Object.assign(this.style, { display: "inline-block", cursor: "pointer" });
          let is    = this.getAttribute("is")    || "plus";
          let color = this.getAttribute("color") || "currentcolor";
          let d = {
            "plus": "m40 80 40 0 0-40 40 0 0 40 40 0 0 40-40 0 0 40-40 0 0-40-40 0z",
            "save": "ADD YOUR OWN ICONS HERE"
          }[ is ];
          this.attachShadow({mode:"open"})
              .innerHTML = `<style>
                              path{fill:${color}}
                              svg{vertical-align:top}
                              svg:hover{color:var(--iconhovercolor,red)}
                            </style>
                            <svg viewBox="0 0 200 200">
                              <path d="${d}" stroke="${color}"/>
                            </svg>`;
          this.onclick = (evt) => {
               console.log("You clicked me!", is);
          }
          this.onmouseover = (evt) => {
            //
          }
        }});
    </script>

    <load-file> for larger, external SVG (loaded into shadowDOM)

    If you do have large SVGs, and can keep them external,
    you can use the <load-file> Web Component I blogged about

    Or for SSG

    You can use a declarative shadowDOM (without using any JavaScript)

    (jan 2024) Almost supported in all Browsers… we are waiting for FireFox.. looks like it will be available in the next FireFox release

    <svg-plus>
      <template shadowrootmode="open">
        <style>
          path     { fill:currentcolor }
          svg      { vertical-align:top; width:120px }
          svg:hover{ color:green }
        </style>
        <svg viewBox="0 0 200 200">
          <path d="m40 80 40 0 0-40 40 0 0 40 40 0 0 40-40 0 0 40-40 0 0-40-40 0z"/>
        </svg>  
      </template>
    </svg-plus>
    
    <svg-min>
      <template shadowrootmode="open">
        <style>
          path     { fill:currentcolor }
          svg      { vertical-align:top; width:120px }
          svg:hover{ color:green }
        </style>
        <svg viewBox="0 0 200 200">
          <path d="M80 80l40 0 40 0 0 40-40 0-80 0 0-40z"/>
        </svg>  
      </template>
    </svg-min>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search