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.
Related Topics
Why Can't Inline Elements Be Transformed
Small Space Between Box Shadow and Div When Alpha Set
Using Conditional Comments in HTML
Default CSS Overriding Media Query
Advanced CSS Selector - Select Based on Styling
How to Code an Arrow Using CSS
Positioning Context on Table-Cell Element in Firefox
Less Class Name String Interpolation Not Working
Css: How to Add White Space Before Element's Content
Stop PHPstorm File Watchers Running Recursively (With Autoprefixer)
Is It Posible to Make an Input Checkbox a Bootstrap Glyphicon
Target First Letter of Each Word in CSS
Position Element at Bottom Right Corner of Current Window
Change Ie Background Color on Unopened, Focused Select Box
Excluding an Element from Nth-Child Pattern