Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using CSS to transition the fill property of an SVG path on hover

I'm including an SVG image file on my page within an object tag, like this:

<object type="image/svg+xml" data="linkto/image.svg">
   <!-- fallback image in CSS -->
</object>

The image in question is a world map, i want to transition the fill property when the mouse hovers over a group, in this case I've grouped my SVG by continent, so South America looks something like this:

<g id="south_america">
    <path fill="#FAFAFA" d="(edited for brevity)"/>
</g>

I can get the fill property to change on hover by using the following CSS at the top of my SVG document:

<style>
#south_america path {
    transition: fill .4s ease;
}
#south_america:hover path {
    fill:white;
}
</style>

But I can't get the fill colour to fade in with a CSS transition, the colour just changes instantly, can anyone shed light on this please?

like image 370
David Alsbright Avatar asked Nov 15 '13 23:11

David Alsbright


People also ask

Can you change color of SVG on hover?

Target the . icon class in CSS and set the SVG fill property on the hover state to swap colors. This is by far the easiest way to apply a colored hover state to an SVG.

Can I change the color of an SVG with CSS?

You can't change the color of an image that way. If you load SVG as an image, you can't change how it is displayed using CSS or Javascript in the browser. If you want to change your SVG image, you have to load it using <object> , <iframe> or using <svg> inline.

Is CSS transition only for hover?

But transitions are not just limited to use with :hover . You can animate CSS properties, thus use CSS transitions without hover. This is done via transitions using some other CSS techniques, a number of which I've outlined below.


2 Answers

In order to transition/fade, CSS needs a starting value and an ending value.
Because you set the color for the path using the SVG attribute fill="#FAFAFA", CSS doesn't process it and the transition doesn't fade.

Instead if you use CSS to set the color, the transition will behave as expected

So all I had to do to make the transition work is give the #europe a starting fill to transition from.

 path { transition: fill .4s ease; }
 /* set fill for before and for during hover */
 #europe       path { fill: red; }
 #europe:hover path { fill: white; }

Here's a working JSFiddle.


Or, doing it inline can be more convenient (style=""):

<path style="fill: #FAFAFA;" d="..."/>

Just in order for CSS to do your fading, it needs to handle the start and end values in CSS/inline style (as opposed to using the SVG fill= attribute).

like image 91
Robbie Wxyz Avatar answered Oct 24 '22 03:10

Robbie Wxyz


Note that to style an SVG via CSS from within an HTML document, the SVG has to be embedded within the HTML of the page, i.e. it doesn't work by embedding it via <object> or <img> in HTML or via background-image etc. in CSS.

When it's embedded within your HTML, you can then style all its elements like you style HTML elements using a CSS selector to match the element(s) you want to style and applying the appropriate styles to it. Besides fill there is a bunch of other SVG attributes, which are also CSS properties. A list of them can be found in the SVG specification or on MDN.

In order for a transition to work, both the start and the end value have to be defined in CSS. So, instead of defining the fill color via the fill attribute (fill="#FAFAFA"), it needs to be defined either via the style attribute, which looks like this:

<path style="fill: #FAFAFA;" d="..."/>

or via a CSS rule packed in a <style> element within the SVG:

<style type="text/css">
  #south-america > path {
    fill: #FAFAFA;
  }
</style>

In both cases you can then transition the values via the CSS rule you mentioned.

Embedding the SVG within HTML has the advantage that you can do the styling from within the stylesheet you use for your HTML, so you can define styling that are shared between the HTML of your page and the embedded SVG.

like image 40
Sebastian Zartner Avatar answered Oct 24 '22 03:10

Sebastian Zartner