Animated gradient background using only CSS
Tags: css3, frontend, tutorial, snippet
Published: 2021-09-17 15:32:53

Have you ever had to create an element that has a gradient as a background and the colors of the gradient are inverted upon hover? The answer is certainly "Yes".

## 👣 First steps
First we need an element that has a gradient background (from `#3DE9BD` to `#2FB594`) to animate: I have chosen to use a button.

💡 Curiosity - today the css `linear-gradient()` function is supported by all browsers, but for some old versions of some of these (Firefox, Internet Explorer) there is no full compatibility and to display the gradient correctly it is necessary to use a prefix. In this regard, there are autoprefix tools for css that take care of inserting any prefixes based on the browser versions that must be supported by the project.

It’s time to talk about animation.
To animate any other property of an element with css we use the css transition property, but in the case of a gradient this is not possible. Now I will share with you two alternatives to solve the problem.

## 1️⃣ Solution 1 – using `::before` and `::after`
The first solution is to use the `::before` and `::after` pseudo-elements.

We set the positioning of the button as relative so that we can position the two pseudo-elements absolutely inside it with 100% width and height to cover its entire size.

At this point, to `::before` we assign as background a gradient from `#3DE9BD` to `#2FB594` and set its opacity to 1 while to `::after` we set the gradient with inverted colors, i.e. from `#2FB594` to `#3DE9BD` and opacity 0.

To both we add the transition property to get an animation when we hover the button with the mouse. Also on hover, the opacity values ​​will have to reverse: `::before`‘s opacity becomes 0 and `::after`‘s opacity becomes 1.

We are almost there, now we have to make sure that the text of the button is visible and not covered by the two pseudo-elements: just insert the text within a `<span>` tag and assign it a relative positioning and a z-index equal to 1.

{% codepen https://codepen.io/giuliamalaroda/pen/eYWPEJP %}

🏆 Goal achieved!

## 2️⃣ Solution 2 – using `<span>`
Let’s suppose that for some reason we need one of the two pseudo-elements for our button, for example we need to show an icon, we need to use some other element to achieve our purpose.

And why not use a `<span>`?
`<span>` has no semantic implications, so it’s the perfect solution.

First of all, also for this solution we must assign the relative positioning to the button to position the `<span>` absolutely and fix its width and height at 100%.

Next step? Simple: we exploit the pseudo-elements of the `<span>` by giving it exactly the same characteristics as in solution 1. We insert the text inside a second `<span>` to which we assign a relative positioning and a z-index equal to 1 and…

{% codepen https://codepen.io/giuliamalaroda/pen/MWmPvmz %}

🏆 The game is done!

## 🎓 Conclusion
With these two simple methods we get the expected result without making use of infinite lines of code or javascript libraries, but simply by writing a few more lines of css.

In any case, my hope is that in the near future not even this work-around is necessary and that the goal can be reached with a simple transition.

Fingers crossed 🤞🏼😉