Long story short - you can't animate a CSS background. Anything that goes into
background-image, including gradients, are stuck that way. The workaround is that a few of the other background properties are animatable.
On my CodePen profile I've got an "animated header" with a gradient. Truth be told, I made a gradient that is actually three or four times the size of the box, setting the
background-size to something like 300% or 400%. Then what I'm actually animating is the
background-position property. The gradient isn't actually changing; it's sliding back and forth, and the viewable area looks alive as a result.
Here's another example, this time a button:
Clicking or pressing that button creates this wave effect that satisfyingly feels like you did the thing. That effect is made with a radial gradient. Because we can't animate the gradient itself, I started the gradient very very small, and animated the
background-size property. If I had loads of free time I'd play around with a JS-detects-where-you-tap mechanism and make the gradient start at that point instead, but you get the idea. There's a lot you can do with this.
I found a gotcha while making this button though. A background's "drawable area" is only as big as the element. When I started, using the button itself as the element, the circle I was scaling up was actually clipped on the sides, making it look either flat on the top and bottom or just clipped all the way to a square. To get around this, I put the background on an ::after pseudo-element that was much larger than the button itself. Then I put an
overflow: hidden on the button to contain the leakage.