Animating Gradients in CSS
Have you ever tried to animate a background in CSS with a linear-gradient? If so, then you most likely stumbled upon the same issue as I did.
The following code show’s the most simple approach I would start with, when it comes to animate the background.
body {
margin: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
animation: animate-bg 2s infinite;
}
@keyframes animate-bg {
from {
background: linear-gradient(yellow, dodgerblue);
}
to {
background: linear-gradient(dodgerblue, yellow);
}
}
We define an animation on the body element which changes the gradient background from black-white to white-black.
However, we can see that it doesn’t work as expected. The color changes immediately, without any animation or smooth transition.
How to solve it
Some solutions to this are animating the background-position
which generates the same effect. We can see it in the following code:
body {
background: linear-gradient(-45deg, #EA225E, #C22286, #612E8D);
background-size: 200% 200%;
animation: GradientBackground 10s ease infinite;
}
@keyframes GradientBackground {
0%, 100% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
};
However, it somehow feels hacky to me, as we need to define an extra large background of which we then animate a changing position. Why can’t we just flip the colors of the gradient?
A better approach — using modern CSS @property
With the release of the CSS Properties and Values API, we actually can do this! This API exposes low-level functionality of the CSS rendering engine, enabling developers with more powerful styling.
In our case, we define a new CSS Custom Property. However, we use the @property syntax to declare it.
By setting the syntax property, we can specify the exact type of property, such as color
, number
, length
, and many more.
@property --gradPoint {
syntax: '<percentage>';
inherits: false;
initial-value: 0%;
}
Instead of changing the background property in our animation, we change the value of the colors of it. To make it work, we define two color variables using the @property
syntax.
Then, we define an animation which changes their color from black to white and vice versa.
Finally, we apply this animation to our body element.
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
animation: animate-color 3s ease-in-out infinite alternate;
background: linear-gradient(var(--color), var(--color-second));
}
@keyframes animate-color {
to {
--color-1: yellow;
--color-2: dodgerblue;
}
}
@property --color {
syntax: '<color>';
inherits: false;
initial-value: red;
}
@property --color-second {
syntax: '<color>';
inherits: false;
initial-value: blue;
}
And this is what we get
A smooth transition between the color changes 🎉
more articles
Newsletter
Subscribe to get notified about new articles and updates.
Thanks for subscribing! You will receive an email shortly.