Fond coloré avec texture

Problématique

On veut appliquer une texture à un élément, donc une image de fond répétable. Mais l’on souhaiterait pouvoir utiliser cette même texture pour d’autres éléments et que la texture soit colorée différemment.

Solutions

Solution 1

On applique la couleur à l’image dans Photoshop et on créé autant d’images que de colorations voulues.

.vert { background: url(pattern_vert.jpg) left top repeat; }
.rouge { background: url(pattern_rouge.jpg) left top repeat; }

Cela aura l’avantage de fonctionner partout mais cette solution souffre de multiples inconvénients:

  • cela alourdit légèrement le chargement de la page dans la mesure où le navigateur télécharge plusieurs images
  • si l’on veut modifier et/ou ajouter une coloration, on doit créer une nouvelle image, la mettre en ligne, modifier le CSS en conséquence, …, c’est une perte de temps
  • pas d’effet de transition possible, par exemple, si l’on souhaite que la coloration change au survol

Solution 2

On n’utilise qu’une seule image (sans coloration particulière), et le pseudo-élément :before (ou :after) pour la coloration. Le principe est bateau, l’élément doit être en positionnement relatif avec l’image en fond, le pseudo-élément en absolu (top, bottom, left et right à 0) avec une couleur de fond en transparence. Cela fonctionnera pour 99.98% des utilisateurs (Internet Explorer ne comprend les pseudo-éléments et les couleurs exprimées en RGBA qu’à partir d’IE 8).

.element { 
	position: relative;
	background: url(pattern.jpg) left top repeat;
}
.element:before {
	content: '';
	position: absolute;
	top: 0;
	left: 0;
	bottom: 0;
	right: 0;
	opacity: 0.5;
}
.element.rouge:before{ background-color: red; }
.element.vert:before{ background-color: green; }

Si l’on n’a plus les inconvénients de la solution précédente, il y en a d’autres:

  • cette solution consiste à recouvrir la texture par une couleur plus ou moins transparente, les possibilités sont donc assez limitées
  • on utilise un pseudo-élément: concrètement ce type de solution permet d’implémenter bon nombre de tricks, effets, …, c’est commode mais la tentation est grande d’en abuser. On se retrouve parfois coincé car l’on a déjà utilisé les deux pseudo-éléments disponibles pour d’autres usages ce qui peut conduire à aller ajouter un div ou un span dans le code HTML pour résoudre le problème. Lorsque l’on résout une problématique de CSS en ajoutant des balises HTML, on est alors en opposition avec le principe de séparation du contenu et de la présentation (mais parfois on n’a pas tellement le choix)
  • le pseudo-élément est en absolu: il faut toujours être prudent avec le positionnement absolu et veiller à gérer l’empilement des éléments positionnés ainsi (z-index)

Solution 3

La propriété CSS background-blend-mode définit la façon dont les images d’arrière-plan doivent être fusionnées entre elles et avec la couleur d’arrière-plan.

On met l’image ET la couleur en fond de l’élément et on utilise background-blend-mode. On mixe donc l’ensemble selon le mode qui nous convient (voir la documentation de la propriété).

.element { 
	background: url(pattern.jpg) left top repeat;
	background-blend-mode: multiply;
}
.element.rouge{ background-color: red; }
.element.vert{ background-color: green; }

Cela fonctionnera pour 97% des utilisateurs. Pour les autres on dégrade en, par exemple, n’appliquant pas de texture mais uniquement la couleur (via @supports).

Notez qu’on ne peut pas obtenir un résultat identique à la solution précédente de cette façon. Donc en fonction de ce que l’on souhaite on utilisera l’une ou l’autre de ces méthodes.

See the Pen background-blend-mode by web-cooking-factory (@web-cooking-factory) on CodePen.dark