Animating SVG Gradient Background Colors With CSS Custom Properties
Changing SVG colors is easy right?
I certainly thought it should be and in the past it has not been too difficult,
with things like changing the stroke
or fill
of the SVG on hover, but what
about when we want to hover a solid colored SVG icon and have it change to a
gradient? This proved to be much more difficult and led me down several
different paths trying to get it to work.
Table of Contents
- Setting
stroke
andfill
on hover - Using
<linearGradient>
in the SVG code - Using
@property
for the gradient colors - Wrapping up
stroke
and fill
on hover
Setting My first thought was to treat the gradient like any other color and try to set
stroke
and fill
to the gradient on hover. This did not seem to be a thing
that was possible, however, so I needed to keep looking.
<linearGradient>
in the SVG code
Using After the naive approach did not work, I did some research and found a
Stack Overflow Post
that recommended using <linearGradient>
directly in the SVG code and applying
it as the stroke
and fill
on hover. Note: this example uses Tailwind
pretty heavily.
Example
Hover me:
This ultimately did work, but it seemed to be impossible to use transitions to have the colors gradually change, which led to a less than desirable jarring color swap.
@property
for the gradient colors
Using After almost deciding to settle and just accept that I would not be able to fade the colors in and out nicely, I remembered mask-image and, after some searching, stumbled upon this post which inspired the solution utilizing CSS custom properties.
Example
Hover me:
We now have a nice fading in/out transition from a solid color to a gradient.
This is accomplished using @property
and setting our initial start/stop colors
for the gradient to a solid color, and then swapping out those variables for new
start/stop colors on hover.
Wrapping up
I was surprised to learn there was not an easier solution built into CSS, but perhaps there will be one day. It seems like this is a lot of work to accomplish what feels like it should be simpler. Is there a better way to do this that I didn't try? Hit me up on Twitter and let me know! @RobbieTheWagner.