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 we need an element that has a gradient background (from
#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.
The first solution is to use the
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
#2FB594 and set its opacity to 1 while to
::after we set the gradient with inverted colors, i.e. from
#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.
🏆 Goal achieved!
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> 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…
🏆 The game is done!
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 🤞🏼😉