CSS color-mix()

Adam Argyle
Adam Argyle

La fonction CSS color-mix() vous permet de mélanger des couleurs dans l'un des espaces de couleurs compatibles, directement à partir de votre CSS.

Navigateurs pris en charge

  • 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 en restant à l'avant-garde de la spécification CSS sur les couleurs. Il n'existe cependant pas de véritable moyen de mélanger des couleurs en CSS. Pour vous rapprocher, vous devez faire des calculs avec des valeurs de couleur partielles. Voici un exemple réduit de la façon dont le CSS peut simuler le mélange aujourd'hui:

Avant avec TSL
.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 dans CSS. Les développeurs peuvent choisir l'espace de couleurs dans lequel ils mélangent les couleurs et le degré 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);
}

Voilà ce que nous voulons. Flexibilité, puissance et API complètes. aucune info

Mélange de couleurs dans CSS

Le CSS existe dans un monde de plusieurs espaces de couleurs et de gammes de couleurs. Par conséquent, il n'est pas facultatif de spécifier l'espace de couleurs 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 de teinte lors du mélange dans un espace de couleurs cylindrique (lch, oklch, hsl et hwb). - Modifiez les couleurs mélangées en cliquant sur l'une des deux premières cases de couleur. - Utilisez le curseur pour modifier le ratio de mélange. - Code CSS color-mix() généré disponible en bas.

Mélange dans les différents espaces de couleurs

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 la combinaison à vos besoins.

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

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);
Les sept espaces de couleur (s rgb, linear-s rgb, lch, oklch, lab, oklab et xyz) affichent chacun le résultat obtenu en mélangeant le noir et le blanc. Environ cinq nuances différentes sont affichées, ce qui montre que chaque espace colorimétrique génère même un gris différent.
Essayer la démo

Ça a un effet énorme !

Prenons blue et white comme exemple. J'ai choisi cette option parce que la forme d'un espace colorimétrique peut affecter les résultats. Dans ce cas, la plupart des espaces de couleurs passent au violet en passant du blanc au bleu. Il montre également à quel point oklab est un espace de couleurs fiable pour le mélange. Il est le plus proche des attentes de la plupart des gens concernant le 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 de couleur (s rgb, linear-s rgb, lch, oklch, lab, oklab, xyz) affichant chacun des résultats différents. Beaucoup sont roses ou violettes, et rares sont celles qui sont encore bleues.
Essayer la démonstration

Apprendre les effets d'un espace de couleur avec color-mix() permet également de créer des dégradés. 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 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 du noir au blanc dans différents espaces de couleurs.
Essayer la démo

Si vous vous demandez quel espace colorimétrique est "le meilleur", il n'y en a pas. C'est pourquoi il existe autant d'options. De plus, si l'un d'eux était "le meilleur", il n'y aurait pas de nouveaux espaces de couleurs (voir oklch et oklab). Chaque espace de couleur peut avoir un moment unique pour briller et être le bon choix.

Par exemple, si vous voulez un résultat de mix dynamique, utilisez hsl ou hwb. Dans la démonstration suivante, deux couleurs vives (magenta et vert lime) sont mélangées. hsl et hwb produisent tous deux un résultat éclatant, tandis que srgb et oklab produisent des couleurs non saturées.

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

Si vous recherchez de la cohérence et de la subtilité, utilisez oklab. Dans la démonstration suivante, qui mélange le bleu et le noir, hsl et hwb produisent des couleurs trop vives et des 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 démonstration

Passez cinq minutes sur color-mix() Playground à tester différentes couleurs et espaces, et vous commencerez à vous faire une idée des avantages de chaque espace. De plus, attendez-vous à recevoir davantage 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 la teinte

Si vous avez choisi de mélanger dans un espace de couleurs cylindrique, essentiellement tout espace de couleurs avec un canal de teinte h qui accepte un angle, vous pouvez spécifier si l'interpolation passe par shorter, longer, decreasing et increasing. Pour en savoir plus, consultez le guide des couleurs HD.

Voici le même exemple de mélange de bleu et de blanc, mais cette fois, il ne s'agit que des espaces cylindriques avec différentes méthodes d'interpolation des teintes.

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

Voici un autre Codepen que j'ai créé pour vous aider à visualiser l'interpolation des teintes, mais spécifiquement 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 des teintes est spécifiée. Mais faites-lui une étude !

Mélange avec des syntaxes de couleurs variables

Jusqu'à présent, nous avons principalement mélangé des couleurs nommées CSS, 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 de couleurs 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 sont convertis en oklch, puis mélangés. Plutôt cool et flexible.

Ajuster les proportions de mélange

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

Pour commencer, voici un exemple de combinaisons toutes équivalentes (et issues 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 mettent en évidence les cas limites. Le premier ensemble d'exemples montre que 50% n'est pas obligatoire, mais peut être spécifié. Le dernier exemple montre un cas intéressant : lorsque les ratios dépassent 100% lorsqu'ils sont additionnés, ils sont tous limités à 100%.

Notez également que si une seule couleur spécifie un ratio, 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 de manière égale. 1. Si 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 qu'ils ne totalisent pas 100%?

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

Cette combinaison d'un color-mix() génère de la transparence, une transparence 40%. Lorsque les ratios ne totalisent pas 100%, le mélange obtenu n'est pas opaque. Aucune des couleurs ne sera complètement mélangée.

Imbrication de color-mix()

Comme tous les CSS, l'imbrication est gérée correctement et comme prévu. Les fonctions internes sont d'abord résolues 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 auquel vous aspirez.

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 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 d'arrière-plan blanc très clair. 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);
  }
}

Pour ce faire, vous devez mélanger du blanc ou du noir à une couleur de la marque.

Jeu de couleurs intermédiaire

Vous pouvez aller encore plus loin en ajoutant des thèmes clair et sombre. 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 aux sélecteurs d'appliquer un thème de couleur de manière conditionnelle.

Cette démonstration intermédiaire montre également une technique de thématisation des couleurs dans laquelle toutes les couleurs du thème sont listées dans :root. Vous pouvez ainsi les voir tous ensemble et les ajuster si nécessaire. Vous pourrez utiliser les variables telles qu'elles sont définies plus tard dans la feuille de style. Cela évite de 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(). Il reconnaît et met en surbrillance la syntaxe, crée un aperçu du mix juste à côté du style dans le volet "Styles" et permet de choisir d'autres couleurs.

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

Capture d'écran de Chrome DevTools inspectant la syntaxe de mélange de couleurs.

Bon mixage !