:Hover Not Working on Svg When Svg Is in External File

hover not working on svg when svg is in external file

Can't be done with the <img> tag. See: Styling And Animating SVGs With CSS. Near the bottom of the page of this article there's a table with the pros and cons of each SVG embedding technique (ie, img, object, etc.). I have reproduced the table here:

|                      | CSS Interactions | CSS Animations | SVG Animations |
|:--------------------:|:----------------:|:--------------:|:--------------:|
| <img> | No | Yes* | Yes |
| CSS background image | No | Yes* | Yes |
| <object> | Yes* | Yes* | Yes |
| <iframe> | Yes* | Yes* | Yes |
| <embed> | Yes* | Yes* | Yes |
| <svg> (inline) | Yes | Yes | Yes |

*Only if inside <svg>

Use CSS hover with external SVG files?

To get this working you need to insert the SVG in HTML code itself.

Adding an external SVG using src will only allow adding CSS to the overall SVG element and not the interior subtags.

also, can you show some more code? So that it will be better to understand the problem well.

eg:

<!DOCTYPE html>
<html>
<head>
<title>SVG</title>
<style media="screen">
circle:hover{
fill: blue;
}
</style>
</head>
<body>

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

</body>
</html>

SVG file not changing color on hover in React 17

For anyone having the same issue as me,

At first, I didn't realize what to do until @antokhio guided me to look into my SVG file itself, and then I figured out all I needed to do was change fill and stroke values as needed, from none to current!

Follow this article for more guidance, on how to change colors of svg files:
https://dev.to/abachi/how-to-change-svg-s-color-in-react-42g2

SVG mouseover behavior lost when trying to load it from external resource into html

You could include the SVG via an <object> or <iframe> tag instead. Both allow interactivity and scripting, neither of which are allowed by the <img> tag.

Add hover style inside SVG file or tag

When you set it as the content of a pseudo element, your svg is actually a CSS <image>. CSS <image> representing svg documents have the same restrictions as html <img> representing svg:

  • No external resources will get fetched
  • Scripts won't run in the inner document
  • The inner document won't be interactive (i.e no pointer-events)
  • ...

This means that any :hover style in this svg document will be useless.

What you can do however is to set this :hover on the parent .slick-next element and change the content there.

To avoid having to store two svg files on your servers with only the fill that will change, you can use of a hack demonstrated by Lea Verou, which exploits the :target pseudo-class. More info on this here.

You would have to restructure your svg so that you have invisible triggerer elements with [id] attributes, so they can become :target. Then all the logic is made using CSS selectors:

right_arrow.svg

<svg width="28" height="81" viewBox="0 0 28 81" xmlns="http://www.w3.org/2000/svg">
<style>
.slick_next_arrow {
fill:red;
}
/* when loaded from 'right_arrow.svg#hover' */
#hover:target ~ .slick_next_arrow {
fill:green;
}
</style>
<!-- here is our triggerer -->
<g id="hover"></g>
<!-- the visual content -->
<path class="slick_next_arrow" hover="fill:green" fill-rule="evenodd" clip-rule="evenodd" d="M3.73141 1.20959C2.95311 -0.00927037 1.3341 -0.366415 0.115239 0.411883L25.5894 40.3058L0 80.3802C1.21886 81.1585 2.83787 80.8014 3.61617 79.5825L27.4729 42.2216C27.7642 41.7653 27.8965 41.2531 27.884 40.7498C28.1017 40.0409 28.0185 39.2445 27.5881 38.5705L3.73141 1.20959Z"/>
</svg>

And your CSS:

.slick__arrow .slick-next::after {
content : url('right_arrow.svg');
}
.slick__arrow .slick-next:hover::after {
content : url('right_arrow.svg#hover');
}

Here is a more complex live-snippet since we have to workaround the fact we can't host third party files from StackSnippets.

const svg_content = `<svg width="28" height="81" viewBox="0 0 28 81" xmlns="http://www.w3.org/2000/svg">  <style>    .slick_next_arrow {      fill:red;    }    #hover:target ~ .slick_next_arrow {      fill:green;    }/* some goodies */    circle {      display: none;    }    /* hide previous path */    [id^="show_circle"]:target ~ .slick_next_arrow {      display: none;    }    /* show new one */    [id^="show_circle"]:target ~ circle {      display: block;       fill: red;    }    #show_circle_hover:target ~ circle.change-color {      fill: green;    }  </style>  <!-- here are all our triggerers -->  <g id="hover"></g>  <g id="show_circle"></g>  <g id="show_circle_hover"></g>  <path class="slick_next_arrow" hover="fill:green" fill-rule="evenodd" clip-rule="evenodd" d="M3.73141 1.20959C2.95311 -0.00927037 1.3341 -0.366415 0.115239 0.411883L25.5894 40.3058L0 80.3802C1.21886 81.1585 2.83787 80.8014 3.61617 79.5825L27.4729 42.2216C27.7642 41.7653 27.8965 41.2531 27.884 40.7498C28.1017 40.0409 28.0185 39.2445 27.5881 38.5705L3.73141 1.20959Z"/>  <circle cx="14" cy="15" r="12"/>  <circle cx="14" cy="40" r="12" class="change-color"/>  <circle cx="14" cy="65" r="12"/></svg>`;
// StackSnippets force us to make a complex js-powered live demo...// but in production all is done from CSSconst url = URL.createObjectURL( new Blob( [ svg_content ], { type: "image/svg+xml" } ) );
const el = document.querySelector( '.parent' );el.style.setProperty( '--url', 'url(' + url + ')' );el.style.setProperty( '--url-hovered', 'url(' + url + '#hover)' );el.style.setProperty( '--url-circle', 'url(' + url + '#show_circle)' );el.style.setProperty( '--url-circle-hovered', 'url(' + url + '#show_circle_hover)' );
.parent{  display: inline-block;  width: 28px;  height: 90px;}.parent::before {  /* right_arrow.svg */  content: var(--url);}.parent:hover::before {  /* right_arrow.svg#hover */  content: var(--url-hovered);}/* goodies */:checked ~ .parent::before {  /* right_arrow.svg#show_circle */  content: var(--url-circle);}:checked ~ .parent:hover::before {  /* right_arrow.svg#show_circle_hover */  content: var(--url-circle-hovered);}
<input type="checkbox" id="check"><label for="check">change shape</label><br><div class="parent"></div>

Part of SVG changing in animation on hover

This is a slightly hacky way to do it, using a blue circle with a black stroke that starts so thick it fills its interior. Hovering over the circle causes the stroke to shrink to nothing.

.logo-background {    fill: blue;    stroke: black;    stroke-width: 200;    transition: stroke-width 500ms;}.logo-background:hover {    stroke-width: 0;}.logo {  fill: none;  stroke: white;  stroke-width: 5;  pointer-events: none;}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200" height="100px">  <defs>    <clipPath id="circle-clip">      <circle cx="100" cy="100" r="100" />    </clipPath>  </defs>
<circle class="logo-background" cx="100" cy="100" r="100" clip-path="url(#circle-clip)" /> <rect class="logo" x="60" y="60" width="80" height="80" rx="5" ry="5"/></svg>

how to make external svg color's change on hover if it's in a pseudo class in css

I have seen a website did it already as i think in his navigation bar visit https://www.nationalww2museum.org

The navigation bar of this site uses icon fonts, not SVG images. It is not possible to change the color of an external SVG integrated by URL.

Sample Image



Related Topics



Leave a reply



Submit