I have an SVG tag that I want to change the fill color when it's hovered. I have added a style tag inside the SVG tag but it seems that the hover doesn't work while simple stylings work just fine. Here is my SVG tag:
<svg width="28" height="81" viewBox="0 0 28 81" xmlns="http://www.w3.org/2000/svg">
<style type="text/css">
.slick_next_arrow {
fill:red;
}
.slick_next_arrow:hover {
fill:green;
}
</style>
<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>
I have included this svg to the element::after in both ways of:
Adding the whole tag inside content
#slick-views-customer-quotes-carousel-block-main-1 .slick__arrow .slick-next::after {
content : url('data:image/svg+xml; utf8, <svg class="" width="28" height="81" viewBox="0 0 28 81" xmlns="http://www.w3.org/2000/svg"> <style type="text/css"> .slick_next_arrow { fill:blue; } .slick_next_arrow:hover { fill:green; } </style> <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>');
}
as separate SVG file
#slick-views-customer-quotes-carousel-block-main-1 .slick__arrow .slick-next::after {
content : url("../images/right_arrow.svg");
}
but none of them works. Any idea on how to tackle this?
The simplest way to add a mouseover effect is to use the :hover pseudo-selector in CSS, as you would with an HTML element. CSS styles can be put in a separate document or inside a <style> tag inside the SVG itself.
The SVG <style> element allows style sheets to be embedded directly within SVG content. Note: SVG's style element has the same attributes as the corresponding element in HTML (see HTML's <style> element).
One way to change SVG colors on hover is to use CSS. You can add CSS to your HTML file or you can use an external CSS file. To add CSS to your HTML file, you will need to use the <style> 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:
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 CSS
const 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>
But you can access the simple version in this plnkr.
You can consider the use of filter to change the coloration:
.box {
content : url('data:image/svg+xml; utf8, <svg class="" width="28" height="81" viewBox="0 0 28 81" xmlns="http://www.w3.org/2000/svg"> <path class="slick_next_arrow" 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>')
}
.box:hover {
filter:hue-rotate(250deg);
}
<div class="box">
</div>
Related: SVG image inline in CSS
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With