Svg Use Element and :Hover Style

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>

SVG element hovering to cause other SVG elements change

your class name of lower_element is wrong in css. also try this:

html:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<g class="top">
<rect x="149" y="100" width="96.4" height="96.3"/>
</g>
<g class="lower_element">
<rect x="19" y="19" width="35" height="15" />
<rect x="36" y="36" width="36.75" height="15" />
</g>
</svg>

css:

svg {
height: 220px;
width: 400px;
background: grey;
}

.lower_element {
fill: white;
transform-origin: center;
transition-duration: 0.1s;
}

.top {
fill: blue;
transform-origin: center;
transition-duration: 0.1s;
}

.top:hover + .lower_element {
fill: red;
}

Change a svg path when another element is hover

Here's some simple code that shows how to do what you want. I've added comments to the code to describe what each step is doing.

// Find all the <a> elements in the list
var items = document.querySelectorAll("UL.location__list LI A");

// To each of them, add an event handler for when the mouse enters its box, and also when it leaves
items.forEach(item => {
item.addEventListener("mouseover", itemMouseOver);
item.addEventListener("mouseout", itemMouseOut);
});

function itemMouseOver(evt) {
// Get the value of the data-area-id attribute for the <a> we are entering
var areaId = evt.target.dataset['areaId'];
// Use it to find the right circle, and add the class "active" to its class attaribute
document.getElementById(areaId).classList.add("active");
}

function itemMouseOut(evt) {
// Get the value of the data-area-id attribute for the <a> we are entering
var areaId = evt.target.dataset['areaId'];
// Use it to find the right circle, and remove the class "active" from its class attaribute
document.getElementById(areaId).classList.remove("active");
}
/* The default style for a circle */
svg circle {
fill: lightgreen;
}

/* the style for when the circle is hovered */
svg circle.active {
fill: green;
}
<div class="location__wrapper">
<div class="location__content">
<ul class="location__list">
<li class="location__list-item"><a data-area-id="1" class="location__list-link" href="https://www.antibes-juanlespins.com/">Antibes Juan-les-Pins</a></li>
<li class="location__list-item"><a data-area-id="22" class="location__list-link" href="http://bezaudun.fr/">Bézaudun-les-Alpes</a></li>
<li class="location__list-item"><a data-area-id="3" class="location__list-link" href="https://www.biot.fr/">Biot</a></li>
<li class="location__list-item"><a data-area-id="21" class="location__list-link" href="https://bouyon.fr/">Bouyon</a></li>
</ul>
</div>
</div>


<svg width="200" viewBox="0 0 100 100">
<circle id="1" cx="25" cy="25" r="20"/>
<circle id="22" cx="75" cy="25" r="20"/>
<circle id="3" cx="25" cy="75" r="20"/>
<circle id="21" cx="75" cy="75" r="20"/>
</svg>

How to change svg fill on hover

Your problem is that you are styling the original exit SVG on hover. That particular one should work.

However all the other buttons that use <svg><use> will not work because when you hover over them, the mouse event doesn't get passed through to the original one (that use points to).

Instead, you should attach the hover rule to the <svg><use> elements instead.
You can apply a style to them, and it will inherited by the original used instance.

.exit {
width: 47.63px;
height: 47.63px;
border: none;
background: none;
padding: 0;
}


.exit:hover svg {
fill: green;
}
<p>original</p>
<button class="exit" type="button" aria-label="Close">
<svg width="100%" height="100%" viewBox="-144 -144 288 288">
<g id="exit">
<title>exit</title>
<circle class="exitCircle" cx="0" cy="0" r="144" fill="transparent"/>
<path class="exitHover" d="m-143 0a143 143 0 1 1 286 0 143 143 0 0 1 -286 0m128-112a113 113 0 0 0 -97 97h97zm-97 127a113 113 0 0 0 97 97v-97zm127 97a113 113 0 0 0 97 -97h-97zm97-127a113 113 0 0 0 -97 -97v97z" transform="rotate(45)" fill="red" />
</g>
</svg>
</button>

<p><use></p>
<button class="exit" type="button" aria-label="Close">
<svg width="100%" height="100%" viewBox="-144 -144 288 288">
<use href="#exit" />
</svg>
</button>

Why doesn't :hover work inside of a symbol in SVG? (In Chrome)

This is actually an interesting case, and while Temani Afif gave the right solution, I think it is worth a few more words in a separate answer.

First off, the question is not where the <style> tag sits. It could really be anywhere. The real question is raised by the :hover selector.