CSS color-mix()

Adam Argyle
Adam Argyle

La fonction CSS color-mix() vous permet de mélanger des couleurs dans n'importe quel espace colorimétrique compatible, directement depuis votre CSS.

Navigateurs pris en charge

  • 111
  • 111
  • 113
  • 16,2

Source

Avant color-mix(), pour assombrir, éclaircir ou désaturer une couleur, les développeurs utilisaient des préprocesseurs CSS ou calc() sur les canaux de couleur.

Avant avec SCSS
.color-mixing-with-sass {
  /* Sass: equally mix red with white */
  --red-white-mix: color.mix(red, white);
}

Sass a fait un excellent travail en gardant une longueur d'avance sur la spécification CSS de couleur. Toutefois, il n'y a pas eu de véritable moyen de mélanger les couleurs en CSS. Pour vous rapprocher, vous devez effectuer des calculs sur des valeurs de couleur partielles. Voici un exemple réduit illustrant la façon dont le CSS peut simuler le mixage aujourd'hui:

Avant avec HSL
.color-mixing-with-vanilla-css-before {
  --lightness: 50%;
  --red: hsl(0 50% var(--lightness));

  /* add "white" to red
     by adding 25% to the lightness channel
  */
  --lightred: hsl(0 50% calc(var(--lightness) + 25%);
}

color-mix() permet de combiner des couleurs en CSS. Les développeurs peuvent choisir l'espace colorimétrique dans lequel ils se mélangent et la prédominance de chaque couleur dans le mélange.

Après
.color-mixing-after {
  /* equally mix red with white */
  --red-white-mix: color-mix(in oklab, red, white);

  /* equally mix red with white in srgb */
  --red-white-mix-srgb: color-mix(in srgb, red, white);
}

C'est ce que nous voulons. Flexibilité, puissance et API complètes. Aimez.

Mélanger des couleurs en CSS

Le code CSS existe dans un univers avec plusieurs espaces de couleurs et gammes de couleurs. De ce fait, il n'est pas facultatif de spécifier un espace colorimétrique pour le mélange. De plus, différents espaces de couleur peuvent modifier considérablement les résultats d'un mélange. Connaître les effets d'un espace de couleur vous aidera donc à obtenir les résultats dont vous avez besoin.

Pour une introduction interactive, essayez cet outil color-mix() : - Explorez les effets de chaque espace colorimétrique. - Explorez les effets de l'interpolation des teintes lors du mélange dans un espace colorimétrique cylindrique (lch, oklch, hsl et hwb). - Modifiez les couleurs mélangées en cliquant sur l'une des deux cases de couleur du haut. - Utilisez le curseur pour modifier le ratio de mélange. - Code CSS color-mix() généré disponible en bas.

Mélanger les différents espaces de couleurs

L'espace colorimétrique par défaut pour le mélange (et les dégradés) est oklab. Elle fournit des résultats cohérents. Vous pouvez également spécifier d'autres espaces de couleur pour adapter le mélange à vos besoins.

Prenons l'exemple de black et white. L'espace colorimétrique dans lequel ils se mélangent ne fera pas une grande différence, n'est-ce pas ? Impossible.

color-mix(in srgb, black, white);
color-mix(in srgb-linear, black, white);
color-mix(in lch, black, white);
color-mix(in oklch, black, white);
color-mix(in lab, black, white);
color-mix(in oklab, black, white);
color-mix(in xyz, black, white);
Sept espaces colorimétriques (srgb, linear-srgb, lch, oklch, lab, oklab, xyz) affichent chacun le résultat d'un mélange de noir et de blanc. Environ cinq nuances différentes sont présentées, ce qui prouve que chaque espace colorimétrique va même se mélanger différemment à un gris.
Essayer la version de démonstration

Cela a un effet énorme !

Prenons blue et white comme autre exemple. J'ai choisi cette option spécifiquement parce que la forme d'un espace colorimétrique peut affecter les résultats. Dans ce cas, c'est que la plupart des espaces de couleur passent au violet lorsqu'ils passent du blanc au bleu. Cela montre également à quel point oklab est un espace de couleurs si fiable pour le mélange, qu'il est le plus proche des attentes de la plupart des utilisateurs concernant le mélange du blanc et du bleu (pas de violet).

color-mix(in srgb, blue, white);
color-mix(in srgb-linear, blue, white);
color-mix(in lch, blue, white);
color-mix(in oklch, blue, white);
color-mix(in lab, blue, white);
color-mix(in oklab, blue, white);
color-mix(in xyz, blue, white);
Sept espaces de couleurs (srgb, linear-srgb, lch, oklch, lab, oklab, xyz) chacun avec des résultats différents. Beaucoup sont roses ou violets, mais peu sont encore bleus.
Essayer la version de démonstration

Apprendre les effets d'un espace colorimétrique avec color-mix() est également une excellente connaissance pour créer des dégradés. La syntaxe de Color 4 permet également aux dégradés de spécifier l'espace colorimétrique, où un dégradé affiche le mélange sur une zone de l'espace.

.black-to-white-gradient-in-each-space {
  --srgb: linear-gradient(to right in srgb, black, white);
  --srgb-linear: linear-gradient(to right in srgb-linear, black, white);
  --lab: linear-gradient(to right in lab, black, white);
  --oklab: linear-gradient(to right in oklab, black, white);
  --lch: linear-gradient(to right in lch, black, white);
  --oklch: linear-gradient(to right in oklch, black, white);
  --hsl: linear-gradient(to right in hsl, black, white);
  --hwb: linear-gradient(to right in hwb, black, white);
  --xyz: linear-gradient(to right in xyz, black, white);
  --xyz-d50: linear-gradient(to right in xyz-d50, black, white);
  --xzy-d65: linear-gradient(to right in xyz-d65, black, white);
}
Dégradés noirs vers blancs dans différents espaces de couleurs
Essayer la version de démonstration

Si vous vous demandez quel espace colorimétrique est « le meilleur », il n'y en a pas. C'est pourquoi il y a tant d'options ! De plus, aucun nouvel espace de couleur n'est inventé (voir oklch et oklab), si l'un d'eux était "le meilleur". Chaque espace colorimétrique peut avoir un moment unique pour briller et être le bon choix.

Par exemple, pour obtenir un résultat de mixage éclatant, utilisez hsl ou hwb. Dans la démonstration suivante, deux couleurs vives (magenta et citron vert) sont mélangées, et les couleurs HSL et HWB produisent toutes les deux un résultat éclatant, tandis que srgb et oklab produisent des couleurs insaturées.

Les résultats du mix sont décrits dans le paragraphe précédent.
Essayer la version de démonstration

Si vous recherchez de la cohérence et de la subtilité, utilisez oklab. Dans la démonstration suivante, qui associe le bleu et le noir, le HTL et le HWB produisent des couleurs trop vives et aux teintes décalées, tandis que srgb et oklab produisent un bleu plus foncé.

Les résultats du mix sont décrits dans le paragraphe précédent.
Essayer la version de démonstration

Passez cinq minutes sur color-mix() Playground, en testant différentes couleurs et différents espaces, et vous commencerez à vous faire une idée des avantages de chaque espace. Attendez-vous également à recevoir davantage de conseils sur les espaces de couleur à mesure que nous nous adaptons à leur potentiel dans nos interfaces utilisateur.

Ajuster la méthode d'interpolation de teinte

Si vous avez choisi de mélanger un espace de couleur cylindrique, c'est-à-dire tout espace colorimétrique avec un canal de teinte h qui accepte un angle, vous pouvez spécifier si l'interpolation doit être shorter, longer, decreasing et increasing. Pour en savoir plus, consultez ce guide de la couleur HD.

Voici le même exemple de mélange bleu-blanc, mais cette fois, ce n'est que dans les espaces cylindriques avec des méthodes d'interpolation de teinte différentes.

Les résultats du mix sont décrits dans le paragraphe précédent.
Essayer la version de démonstration

Voici un autre codepen que j'ai créé pour aider à visualiser l'interpolation des teintes, mais plus particulièrement pour les gradients. Je pense que cela vous aidera à comprendre comment chaque espace de couleur produit son résultat de mélange lorsque l'interpolation de teinte est spécifiée, cependant, faites-lui une étude !

Mélange avec différentes syntaxes de couleurs

Jusqu'à présent, nous avons principalement mélangé des couleurs CSS nommées, comme blue et white. Le mélange de couleurs CSS est prêt à mélanger des couleurs provenant de deux espaces de couleurs différents. C'est une autre raison pour laquelle il est essentiel de spécifier l'espace colorimétrique pour le mélange, car cela définit l'espace commun lorsque les deux couleurs ne sont pas dans le même espace.

color-mix(in oklch, hsl(200deg 50% 50%), color(display-p3 .5 0 .5));

Dans l'exemple précédent, hsl et display-p3 seront convertis en oklch, puis mélangés. Plutôt cool et flexible.

Ajuster les ratios de mélange

Il est peu probable que, chaque fois que vous mélangez, vous souhaitiez des parties égales de chaque couleur, comme l'ont montré la plupart des exemples jusqu'à présent. Bonne nouvelle, il existe une syntaxe pour articuler la quantité de chaque couleur à voir dans le mix résultant.

Pour commencer, voici quelques exemples de mix qui sont tous équivalents (et disponibles dans les spécifications):

.ratios-syntax-examples {
  /* omit the percentage for equal mixes */
  color: color-mix(in lch, purple, plum);
  color: color-mix(in lch, plum, purple);

  /* percentage can go on either side of the color */
  color: color-mix(in lch, purple 50%, plum 50%);
  color: color-mix(in lch, 50% purple, 50% plum);

  /* percentage on just one color? other color gets the remainder */
  color: color-mix(in lch, purple 50%, plum);
  color: color-mix(in lch, purple, plum 50%);

  /* percentages > 100% are equally clamped */
  color: color-mix(in lch, purple 80%, plum 80%);
  /* above mix is clamped to this */
  color: color-mix(in lch, purple 50%, plum 50%);
}

Je trouve que ces exemples mettent bien en lumière les cas limites. Le premier ensemble d'exemples montre que la valeur 50% n'est pas obligatoire, mais peut être spécifiée de manière facultative. Le dernier exemple illustre un cas intéressant : lorsque les ratios dépassent 100% lorsqu'ils sont additionnés, ils sont également limités à 100 % au total.

Notez également que si une seule couleur spécifie un rapport, l'autre est supposée représenter le reste à 100%. Voici quelques exemples supplémentaires pour illustrer ce comportement.

color-mix(in lch, purple 40%, plum) /* plum assigned 60% */
color-mix(in lch, purple, 60% plum) /* purple assigned 40% */
color-mix(in lch, purple 40%, plum 60%) /* no auto assignments */

Ces exemples illustrent deux règles : 1. Lorsque les ratios dépassent 100%, ils sont limités et répartis équitablement. 1. Lorsqu'un seul ratio est fourni, l'autre couleur est définie sur 100 moins ce ratio.

La dernière règle est un peu moins évidente. Que se passe-t-il si des pourcentages sont fournis pour les deux couleurs et que leur somme totale n'est pas égale à 100%?

color-mix(in lch, purple 20%, plum 20%)

Cette combinaison de color-mix() permet d'obtenir de la transparence et du 40%. Lorsque la somme des ratios n'est pas égale à 100%, le mix résultant ne sera pas opaque. Aucune des deux couleurs ne sera complètement mélangée.

Imbrication color-mix()

Comme tous les CSS, l'imbrication est gérée correctement et comme prévu. Les fonctions internes sont résolues en premier et renvoient leurs valeurs au contexte parent.

color-mix(in lch, purple 40%, color-mix(plum, white))

N'hésitez pas à imbriquer autant d'éléments que nécessaire pour obtenir le résultat souhaité.

Créer un jeu de couleurs clair et sombre

Créons des jeux de couleurs avec color-mix().

Un jeu de couleurs de base

Dans le code CSS suivant, un thème clair et un thème sombre sont créés en fonction de la couleur hexadécimale de la marque. Le thème clair crée deux couleurs de texte bleu foncé et une couleur de surface blanche très claire à l'arrière-plan. Ensuite, dans une requête multimédia de préférence sombre, de nouvelles couleurs sont attribuées aux propriétés personnalisées afin que l'arrière-plan soit sombre et que les couleurs du texte soient claires.

:root {
  /* a base brand color */
  --brand: #0af;

  /* very dark brand blue */
  --text1: color-mix(in oklab, var(--brand) 25%, black);
  --text2: color-mix(in oklab, var(--brand) 40%, black);

  /* very bright brand white */
  --surface1: color-mix(in oklab, var(--brand) 5%, white);
}

@media (prefers-color-scheme: dark) {
  :root {
    --text1: color-mix(in oklab, var(--brand) 15%, white);
    --text2: color-mix(in oklab, var(--brand) 40%, white);
    --surface1: color-mix(in oklab, var(--brand) 5%, black);
  }
}

Tout cela est accompli en mélangeant le blanc ou le noir avec une couleur de marque.

Jeu de couleurs intermédiaire

Pour aller plus loin, ajoutez d'autres thèmes que clair et sombre. Dans la démonstration suivante, les modifications apportées au groupe d'options mettent à jour un attribut sur la balise HTML [color-scheme="auto"], ce qui permet aux sélecteurs d'appliquer un thème de couleurs de manière conditionnelle.

Cette démonstration intermédiaire présente également une technique de thématisation de couleurs dans laquelle toutes les couleurs du thème sont répertoriées dans :root. Cela permet de les voir facilement tous ensemble et de les ajuster si nécessaire. Vous pourrez utiliser les variables telles qu'elles sont définies ultérieurement dans la feuille de style. Cela vous évite de devoir parcourir la feuille de style à la recherche de manipulations de couleurs, car elles sont toutes contenues dans le bloc :root initial.

Cas d'utilisation plus intéressants

Ana Tudor propose une démonstration de qualité avec quelques cas d'utilisation à étudier:

Déboguer color-mix() avec les outils de développement

Les outils pour les développeurs Chrome sont parfaitement compatibles avec color-mix(). Il reconnaît et met en surbrillance la syntaxe, crée un aperçu du mixage juste à côté du style dans le volet "Styles" et permet de choisir d'autres couleurs.

Cela ressemblera à ceci dans les outils de développement:

Capture d'écran des outils pour les développeurs Chrome qui inspectent la syntaxe du mélange de couleurs.

À vous de jouer !