1

What is the correct way to add a hover effect for an SVG that is embedded in an ing tag? Can this purely be achieved by CSS?

If not, what is the correct HTML semantic way to embed SVG icons with hover effects?

Thanks

4
  • Consider using <svg> tag by itself, not embed inside of <img> tag
    – Hao Wu
    Commented Jan 10, 2023 at 5:48
  • Thank you, for accesbility of a navigation icon what is the preferred tag? Commented Jan 10, 2023 at 5:55
  • What's the problem. You can hover the entire image. Is it that you want to hover things within the image, if so, you can't do that. Commented Jan 10, 2023 at 8:19
  • You can't, the IMG tag is a locked container you can't style the inside of. For alternatives you can load the SVG file and inject it in your document Commented Jan 10, 2023 at 13:55

2 Answers 2

1

If the svg icon is made using an embedded image in the format data:image/png;base64 then to change color on hover: you can use svg filter feColorMatrix:

.R1:hover {
filter:url(#RedFilter);
} 

.G1:hover {
filter:url(#GreenFilter);
}
.B1:hover {
filter:url(#BlueFilter);
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="150" viewBox="0 -30 400 150" style="border:1px solid grey;"> 

  <defs>
 <filter id="RedFilter" x="-20" y="-20" width="150" height="150">
        <feColorMatrix in="SourceGraphic" type="matrix"
                values="0 0 0 1 0
                        0 0 0 0 0
                        0 0 0 0 0
                        0 0 0 1 0
                "/>
    </filter> 
    <filter id="GreenFilter" x="-20" y="-20" width="140" height="140">
        <feColorMatrix in="SourceGraphic" type="matrix"
                values="0 0 0 0 0
                        0 0 0 1 0
                        0 0 0 0 0
                        0 0 0 1 0
                "/>
    </filter> 
    
    <filter id="BlueFilter" x="-20" y="-20" width="140" height="140">
        <feColorMatrix in="SourceGraphic" type="matrix"
                values="0 0 0 0 0
                        0 0 0 0 0
                        0 0 0 1 0
                        0 0 0 1 0
                "/>
    </filter> 
    
    <filter id="WhiteFilter" x="-20" y="-20" width="140" height="140">
        <feColorMatrix in="SourceGraphic" type="matrix"
                values="0 0 0 1 0
                        0 0 0 1 0
                        0 0 0 1 0
                        0 0 0 1 0
                "/>
    </filter>
 


   <image id="Building" width="100" height="100"  xlink:href="data:image/png;base64,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"/>   
   </defs> 
    
   <use class="R1" id="BuildingRed" xlink:href="#Building" x="20" y="0"   ></use> 
   <use class="G1" id="BuildingGreen" xlink:href="#Building" x="150" y="0"  ></use> 
    <use class="B1" id="BuildingBlue" xlink:href="#Building" x="280" y="0"  ></use>

Update

When adding an SVG file to HTML using the img tag, the image loses the ability to be styled using simple fill, stroke, etc.
But you can use SVG or CSS filters to change the color on hover.

img:not(:hover) {
  transition: 2s;
  filter: saturate(0%);
  -webkit-filter: saturate(0%);
  }
img:hover {
  transition: 1s;
}
<img width=200 src="https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg">

Another example where the Barrett Sonntag`s utility is used to generate any color using CSS filters.

<style>
.img:hover{
filter: invert(12%) sepia(83%) saturate(5841%) hue-rotate(244deg) brightness(87%) contrast(153%);
 -webkit-filter: invert(12%) sepia(83%) saturate(5841%) hue-rotate(244deg) brightness(87%) contrast(153%);
}
</style>
<img class="img"  src="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/beacon.svg" width="300" height="300" >

4
  • Interesting, I haven't seen a solution like this before. Thanks! Commented Jan 10, 2023 at 14:24
  • What is the approach if the SVG is not PNG based? These are SVGs exported from Illustrator as pure SVGs. Commented Jan 18, 2023 at 4:54
  • @TanookiMario I'll try to give an additional answer with pure SVG added to the HTML using the img tag Commented Jan 18, 2023 at 6:04
  • @TanookiMario Added an edit to the response to your comment Commented Jan 18, 2023 at 6:59
0

You must use <svg> tag instead <img>.

You can check SVG Vectors for your desired type of SVG here.

Sharing an hover example for you.

.html

<div>
  
  <svg width="24" height="24" viewBox="0 0 24 24">
    <path d="M 10,30
       A 20,20 0,0,1 50,30
       A 20,20 0,0,1 90,30
       Q 90,60 50,90
       Q 10,60 10,30 z">
    </path>
  </svg>
  
</div>

.css

svg {
  width: 70px;
  height: 70px;
}
svg:hover {
  fill: red;
}

body {
  display: grid;
  height: 100vh;
  margin: 0;
  place-items: center center;
}

Gives you desired type of output.

enter image description here

Not the answer you're looking for? Browse other questions tagged or ask your own question.