Animating linear-gradient: a guide
Tags: css, webdev, html
Published: 2020-09-22 20:16:58

# Intro

```
div {
  width: 100px;
  height: 100px;
  background-image: linear-gradient(-45deg, peru, papayawhip);
  transition: 0.5s;
}

div:hover{
  background-image: linear-gradient(-45deg, peru, peru);
  transition: 0.5s;
}
```
What's wrong with this code?  It should make a nice, clean, gradient animation, from a gradient to a solid fill.  It should work, right?

**Wrong**

[background-image is not animatable.](https://www.w3schools.com/cssref/pr_background-image.asp)

What's a developer to do?  I lay in my bed and considered the possibilities.  I could use Javascript DOM functions like `backgroundImage` and template literals to change the color.  I could use a RGB to CMYK function, and call requestAnimationFrame.  Or, I could look it up.  
I found [this.](https://stackoverflow.com/questions/23441060/animating-linear-gradient-using-css) 

What this StackOverflow thread suggests is basically increasing the `background-size` to "200% 200%" (I assume double the size of the target window) and then translate it using a bunch of percentages and `background-position`.  
Cool!  After spending a while reading up on documentation, I figured out this:
![Screen Shot 2020-09-22 at 12.52.29 PM](https://dev-to-uploads.s3.amazonaws.com/i/04qldu7htk1vohhcqs2d.png)
 
Assuming `linear-gradient(145deg, red, blue)`, of course.

From the StackOverflow code and my newfound knowledge about background-position, I had my steps.

* Write gradient 
* Increase gradient size
* Center gradient (`50% 50%`) so it looked about the same
* background-position is animatable, so translate either `100% 100%` or `0% 0%` to make it look more blue or more red, respectively

Yay!  Problem solved.  Here's a working demo:
{% codepen https://codepen.io/carlyraejepsenstan/pen/bGpOWxa default-tab=css, result%}

But, as you can probably tell, it's not perfect - `100% 100%` still has some red tinge to it, and on a blue background this div will definitely stand out.  Also, combining a 200% background size and 50% background position changes the gradient slightly - as you can see in this side by side comparison:
![Screen Shot 2020-09-22 at 1.01.43 PM](https://dev-to-uploads.s3.amazonaws.com/i/7zx4kdxvmubv8p96rsjy.png)

What's a perfection obsessed developer like me to do?  After excessive brainstorming, I figured out these things:
* `background-size` is animatable
* Changing the gradient to `red, blue, blue` makes a completely blue portion at one corner.

So my steps now looked like this:
* Start the div with a normal gradient
*On hover, do these things:
  * change background-size to 200%
  * change background-position to 100% 100% (the `blue blue` 
    part of the gradient) 
  * use nicer colors than red and blue

While messing with the code, I found that I didn't need to change the background-size on hover; leaving it 200% to begin with actually helped differentiate the div from the same-colored background.  I also added a quick box-shadow for a cool effect.

And here it is!  A successfully animated linear-gradient, in pure CSS.

{% codepen https://codepen.io/carlyraejepsenstan/pen/ExKGmBY default-tab=css, result %}

Helpful? Confusing? Thoughts?  Please leave a comment!