CSS color-mix()

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

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: 113.
  • Safari: 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 pour rester en avance sur la spécification CSS des couleurs. Cependant, il n'existait pas de véritable moyen de mélanger des couleurs en CSS. Pour vous en approcher, vous devez effectuer des calculs sur des valeurs de couleur partielles. Voici un exemple réduit de la façon dont CSS peut simuler le mélange 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 mélanger des couleurs en CSS. Les développeurs peuvent choisir l'espace colorimétrique dans lequel ils effectuent le mélange et le niveau de 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. aucune info

Mélanger des couleurs en CSS

Le CSS existe dans un monde à plusieurs espaces colorimétriques et gammes de couleurs. Par conséquent, il est obligatoire de spécifier l'espace colorimétrique pour le mélange. De plus, différents espaces colorimétriques peuvent modifier considérablement les résultats d'un mélange. Par conséquent, connaître les effets d'un espace colorimétrique vous aidera à obtenir les résultats dont vous avez besoin.

Pour une introduction interactive, essayez cet outil color-mix() : - Découvrez les effets de chaque espace colorimétrique. - Découvrez les effets de l'interpolation de teinte 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 en haut. - Utilisez le curseur pour modifier le rapport de mélange. - Le code CSS color-mix() généré est disponible en bas.

Mélanger dans les différents espaces colorimétriques

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

Prenons black et white, par exemple. L'espace colorimétrique dans lequel ils sont mélangés 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 les résultats du mélange du noir et du blanc. Environ cinq nuances différentes sont affichées, ce qui montre que chaque espace colorimétrique se mélange même différemment pour former du gris.
Essayer la démonstration

Cela a un impact important.

Prenons blue et white comme autre exemple. J'ai choisi cet exemple spécifiquement, car il s'agit d'un cas où la forme d'un espace colorimétrique peut affecter les résultats. Dans ce cas, la plupart des espaces colorimétriques deviennent violets lorsqu'ils passent du blanc au bleu. Cela montre également à quel point oklab est un espace colorimétrique fiable pour le mélange. Il est le plus proche des attentes de la plupart des utilisateurs en matière de mélange de blanc et de 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 colorimétriques (srgb, linear-srgb, lch, oklch, lab, oklab, xyz) sont présentés, chacun avec des résultats différents. Beaucoup sont roses ou violets, et peu sont encore bleus.
Essayer la démonstration

Apprendre les effets d'un espace colorimétrique avec color-mix() est également très utile pour créer des dégradés too. La syntaxe de la couleur 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 d'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 du noir au blanc dans différents espaces colorimétriques.
Essayer la démonstration

Si vous vous demandez quel est le "meilleur" espace colorimétrique, il n'y en a pas. C'est pourquoi il existe autant d'options. De plus, de nouveaux espaces colorimétriques ne seraient pas inventés (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, si vous souhaitez obtenir un résultat de mélange éclatant, utilisez hsl ou hwb. Dans la démonstration suivante, deux couleurs éclatantes (magenta et vert citron) sont mélangées. Les deux couleurs hsl et hwb produisent un résultat éclatant, tandis que srgb et oklab produisent des couleurs non saturées.

Les résultats de la combinaison, comme décrit dans le paragraphe précédent.
Essayer la démonstration

Si vous souhaitez obtenir cohérence et subtilité, utilisez oklab. Dans la démonstration suivante, qui mélange le bleu et le noir, hsl et hwb produisent des couleurs trop éclatantes et décalées, tandis que srgb et oklab produisent un bleu plus foncé.

Les résultats de la combinaison, comme décrit dans le paragraphe précédent.
Essayer la démonstration

Passez cinq minutes avec le color-mix() bac à sable, en testant différentes couleurs et différents espaces. Vous commencerez à vous familiariser avec les avantages de chaque espace. Attendez-vous également à recevoir plus de conseils sur les espaces colorimétriques à mesure que nous nous adaptons tous à leur potentiel dans nos interfaces utilisateur.

Ajuster la méthode d'interpolation de teinte

Si vous avez choisi de mélanger dans un espace colorimétrique cylindrique, essentiellement n'importe quel espace colorimétrique avec un canal de teinte h qui accepte un angle, vous pouvez spécifier si l'interpolation est shorter, longer, decreasing, et increasing. Ce concept est bien couvert dans ce guide sur la couleur HD si vous souhaitez en savoir plus.

Voici le même exemple de mélange de bleu et de blanc, mais cette fois, il ne se trouve que dans les espaces cylindriques avec différentes méthodes d'interpolation de teinte.

Les résultats de la combinaison, comme décrit dans le paragraphe précédent.
Essayer la démonstration

Voici un autre Codepen que j'ai créé pour visualiser l'interpolation de teinte, mais spécifiquement pour les dégradés. Je pense que cela vous aidera à comprendre comment chaque espace colorimétrique produit son résultat de mélange lorsque l'interpolation de teinte est spécifiée. Étudiez-le.

Mélanger avec différentes syntaxes de couleur

Jusqu'à présent, nous avons principalement mélangé des couleurs nommées en CSS, comme blue et white. Le mélange de couleurs CSS est prêt à mélanger des couleurs provenant de deux espaces colorimétriques différents. C'est une autre raison pour laquelle il est essentiel de spécifier l'espace colorimétrique pour le mélange, car il définit l'espace commun lorsque les deux couleurs ne se trouvent 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. C'est plutôt cool et flexible.

Ajuster les rapports de mélange

Il est peu probable que vous souhaitiez mélanger des parties égales de chaque couleur à chaque fois, comme le montrent la plupart des exemples jusqu'à présent. Bonne nouvelle : il existe une syntaxe pour indiquer la quantité de chaque couleur à afficher dans le mélange obtenu.

Pour commencer ce sujet, voici un exemple de mélanges équivalents (et issus de la spécification) :

.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 illustrent bien les cas extrêmes. Le premier ensemble d'exemples montre que 50% n'est pas obligatoire, mais peut être spécifié de manière facultative. Le dernier exemple montre un cas intéressant où les rapports dépassent 100% lorsqu'ils sont additionnés. Ils sont tous limités à 100%.

Notez également que si une seule couleur spécifie un rapport, l'autre est supposée être 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 rapports dépassent 100%, ils sont limités et répartis de manière égale. 1. Lorsqu'un seul rapport est fourni, l'autre couleur est définie sur 100 moins ce rapport.

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 qu'ils ne totalisent pas 100%?

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

Cette combinaison d'un color-mix() entraîne une transparence de 40%. Lorsque les rapports ne totalisent pas 100%, le mélange obtenu n'est pas opaque. Aucune des couleurs ne sera entièrement mélangée.

Imbriquer color-mix()

Comme pour 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 que nécessaire pour obtenir le résultat souhaité.

Créer un jeu de couleurs claires et sombres

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

Un jeu de couleurs de base

Dans le CSS suivant, un thème clair et un thème sombre sont créés en fonction d'une couleur hexadécimale de marque. Le thème clair crée deux couleurs de texte bleu foncé et une couleur de surface d'arrière-plan blanche très claire. Ensuite, dans une requête mé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 obtenu en mélangeant du blanc ou du noir dans une couleur de marque.

Jeu de couleurs intermédiaire

Vous pouvez aller plus loin en ajoutant plus de thèmes clairs et sombres. Dans la démonstration suivante, les modifications apportées au groupe de boutons radio mettent à jour un attribut sur la balise HTML [color-scheme="auto"] ce qui permet ensuite aux sélecteurs d'appliquer conditionnellement un thème de couleur.

Cette démonstration intermédiaire présente également une technique de thème de couleur dans laquelle toutes les couleurs du thème sont listées dans :root. Cela permet de les voir facilement et de les ajuster si nécessaire. Plus loin dans la feuille de style, vous pouvez utiliser les variables telles qu'elles sont définies. Cela vous évite de devoir parcourir la feuille de style pour les manipulations de couleurs, car elles sont toutes contenues dans le bloc :root initial.

Cas d'utilisation plus intéressants

Ana Tudor propose une excellente démonstration 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(). Ils reconnaissent et mettent en surbrillance la syntaxe, créent un aperçu du mélange juste à côté du style dans le volet "Styles" et permettent de choisir d'autres couleurs.

Voici à quoi cela ressemble dans les outils de développement :

Outils pour les développeurs Chrome inspectant la syntaxe color-mix.

Bon mélange à tous !