Fond en dégradé de couleurs avec transition

Problématique

On souhaite appliquer un fond avec un dégradé entre deux couleurs à un élément. Rien de plus simple avec linear-gradient ! Et on voudrait qu’au survol, le dégradé change. Donc on change le linear-gradient sur l’état :hover. Ça marche, le dégradé change bien au survol mais d’un coup, sans transition. Qu’à cela ne tienne, on ajoute la propriété transition à l’élément. Et ça ne marche pas, notre dégradé change toujours d’un coup. Et pour cause, linear-gradient est une valeur de background-image et non de background-color et faire des transitions entre deux background-image n’est, à l’heure actuelle, pas possible.

Solution

Là, c’est vraiment un trick. L’idée est de reproduire l’effet d’un linear-gradient avec une couleur de fond et une ombre intérieure, soit background-color et box-shadow, qui, eux, permettent les transitions. On applique donc l’une des deux couleurs en fond avec background-color et ensuite on fait un box shadow réglé comme suit (si on est à l’horizontal, donc à adapter pour la verticale) : inset, décalage horizontal à la largeur de l’élément (la couleur sera à gauche, pour la mettre à droite, mettre la valeur en négatif), décalage vertical à 0, flou à la moitié de la largeur de l’élément, étalement à la moitié de largeur de l’élément en négatif. Il n’y a plus qu’à gérer le changement des couleurs au :hover avec transition.

.element { 
	width: 200px;
	background-color: red;
	box-shadow: inset 200px 0 100px -100px green;
}

Remarques

  • Si on compare avec un linear-gradient, on remarquera que le rendu n’est pas identique en réalité, les ombres et les dégradés n’étant pas calculés de la même façon par le navigateur. J’ai fait plusieurs tests en jouant sur différents paramètres mais sans succès. Ceci dit, le résultat est tout de même satisfaisant.
  • box-shadow n’accepte pas l’unité %, la contrainte est donc de taille et limite l’utilisation de ce trick à des cas où l’on connait la dimension de l’élément (en largeur pour un dégradé horizontal, en hauteur pour un vertical).

See the Pen linear-gradient by web-cooking-factory (@web-cooking-factory) on CodePen.dark