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
strokeandfillon hover - Using
<linearGradient>in the SVG code - Using
@propertyfor the gradient colors - Wrapping up
Setting stroke and fill on hover
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.
Using <linearGradient> in the SVG code
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.
Using @property for the gradient colors
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.