CSS color-mix()

Adam Argyle
Adam Argyle

O CSS color-mix() permite que você misture cores, em qualquer um dos espaços de cor suportados, diretamente de seu CSS.

Compatibilidade com navegadores

  • Chrome: 111
  • Borda: 111.
  • Firefox: 113
  • Safari: 16.2.

Origem

Antes de color-mix(), para escurecer, clarear ou dessaturar uma cor, os desenvolvedores usavam Pré-processadores de CSS ou calc() em cores canais.

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

Sass fez muito bem ficar à frente da especificação de cores do CSS. No entanto, ainda não houve uma maneira real de misturar cores no CSS. Para se aproximar, você precisa fazer cálculos valores de cor. Veja um exemplo reduzido de como o CSS pode simular uma mescla hoje:

Antes com 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() traz a a capacidade de misturar cores no CSS. Os desenvolvedores podem escolher qual espaço de cores misturam e qual o grau de dominante de cada cor na mistura.

Depois
.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);
}

É isso que queremos. Flexibilidade, eficiência e APIs completas. Curta,

Mistura de cores no CSS

O CSS existe em um espaço de várias cores e gama de cores, e por isso especificar o espaço de cores para mistura não é opcional. Além disso, diferentes os espaços de cor podem alterar drasticamente os resultados de uma mistura. Portanto, saber os efeitos de um espaço de cores ajudará você a obter os resultados que precisa.

Para uma introdução interativa, teste esta ferramenta color-mix(): - Explorar os efeitos de cada espaço de cor. - Explorar os efeitos da interpolação de matiz ao misturar uma cor cilíndrica (lch, oklch, hsl e hwb). - Alterar as cores que estão sendo misturadas clicando em uma das duas caixas de cores superiores. - Use o controle deslizante para alterar a proporção da mistura. - Código CSS color-mix() gerado, disponível na parte inferior.

Misturando os vários espaços de cores

O espaço de cores padrão para mistura (e gradientes) é oklab. Oferece resultados consistentes. Você também pode especificar espaços de cor alternativos, para adaptar o de acordo com suas necessidades.

Veja black e white, por exemplo. O espaço de cores que eles misturam não fará uma grande diferença, certo? Errado.

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);
Sete espaços de cor (s rgb, linear-s rgb, lch, oklch, lab, oklab, xyz) mostram os resultados da mistura de preto e branco. Aproximadamente cinco tons diferentes são mostrados, demonstrando que cada espaço de cor se misturará ao cinza de maneira diferente.
Confira a demonstração

Isso tem um grande efeito!

Veja blue e white para outro exemplo. Escolhi isso especificamente porque é um caso em que a forma de um espaço de cor pode afetar os resultados. Nesse caso, é que a maioria dos espaços de cor fica roxo ao passar do branco para o azul. Ela também mostra como oklab é um espaço de cores tão confiável para mistura, é o mais próximo das expectativas da maioria das pessoas de misturar branco e azul (sem roxo).

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);
Sete espaços de cor (s rgb, linear-s rgb, lch, oklch, lab, oklab, xyz) exibidos com resultados diferentes. Muitos são rosa ou roxo, alguns ainda são azuis.
Confira a demonstração

Aprender os efeitos de um espaço de cores com color-mix() é um ótimo conhecimento para como criar gradientes também. A sintaxe da Cor 4 também permite que os gradientes especifiquem o espaço de cores, em que uma o gradiente mostra a mistura de uma área do espaço.

.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);
}
Gradientes de preto a branco em diferentes espaços de cor.
Confira a demonstração

Se você está se perguntando qual espaço de cores é "o melhor", não existe uma. É por isso que há muitas opções. Também não haveria novos espaços de cor sendo foi inventado (consulte oklch e oklab), se um fosse "o melhor". Cada cor pode ter um momento único para brilhar e ser a escolha certa.

Por exemplo, se você quiser um resultado de mixagem vibrante, use hsl ou hwb. Nos seguintes demonstração, duas cores vibrantes (magenta e limão) são misturadas e hsl e hwb ambos produzem um resultado vibrante, enquanto s rgb e oklab produzem cores não saturadas.

A combinação resulta, conforme descrito no parágrafo anterior.
Veja a demonstração

Se quiser consistência e sutileza, use o oklab. Na demonstração a seguir, que combina azul e preto, hsl e hwb produzem cores excessivamente vibrantes e matizes alteradas, sRGB e oklab produzem um azul mais escuro.

A combinação resulta, conforme descrito no parágrafo anterior.
Veja a demonstração

Passe cinco minutos com o Playground color-mix(), testando cores diferentes e espaços para começar a ter uma ideia das vantagens de cada um deles. Além disso, esperam mais orientações sobre os espaços de cor à medida que nos ajustamos às potencial em nossas interfaces de usuário.

Ajustar o método de interpolação de matiz

Se optar por misturar em um espaço de cores cilíndrico, essencialmente qualquer cor com um canal de matiz h que aceite um ângulo, será possível especificar se o a interpolação é shorter, longer, decreasing e increasing. Isso é abordado bem neste Guia de cores de alta definição, se quiser saber mais.

Aqui está o mesmo exemplo de combinação de azul para branco, mas, desta vez, está apenas no espaços cilíndricos com diferentes métodos de interpolação de matiz.

A combinação resulta, conforme descrito no parágrafo anterior.
Veja a demonstração

Este é outro Codepen que fiz para ajudar a visualizar a interpolação de matiz, mas especificamente para gradientes. Acredito que isso ajudará você a entender como cada o espaço de cores produz seu resultado de mistura quando a interpolação de matiz é especificada, um estudo!

Mistura com sintaxes de cores variadas

Até agora, misturamos principalmente cores com nomes CSS, como blue e white. Cor do CSS a mistura está pronta para misturar cores que são de dois espaços de cor diferentes. Isso é outro motivo é que é fundamental especificar o espaço de cores para a mistura, já que define o espaço comum para quando as duas cores não estão no mesmo espaço.

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

No exemplo anterior, hsl e display-p3 serão convertidos em oklch. e depois misturados. Muito legal e flexível.

Como ajustar as proporções de mistura

É improvável que, toda vez que você mistura você queira partes iguais de cada cor, como a maioria dos exemplos até agora mostrou. Boas notícias, há uma sintaxe para articular quanto de cada cor deve ser visto na mistura resultante.

Para começar, aqui está um exemplo de mixes que são todos equivalentes (e de acordo com as especificações):

.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%);
}

Esses exemplos ilustram bem os casos extremos. O primeiro conjunto de os exemplos mostram que 50% não é obrigatório, mas pode ser especificado como opção. A última exemplo mostra um caso interessante de quando as proporções excedem 100% quando adicionadas elas são igualmente ajustadas para totalizar 100%.

Observe também que, se apenas uma cor especificar uma proporção, presume-se que a outra seja o restante para 100%. Aqui estão mais alguns exemplos que ajudam a do seu modelo.

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 */

Esses exemplos ilustram duas regras: 1: Quando as proporções excedem 100%, elas são ajustadas e distribuídas igualmente. 1. Quando apenas uma proporção é fornecida, a outra cor é definida como 100 menos essa proporção.

A última regra é um pouco menos óbvia; o que acontece se as porcentagens forem fornecidas para ambas as cores e elas não totalizam 100%?

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

Essa combinação de color-mix() resulta em transparência e 40% em transparência. Quando as proporções não somam 100%, a mistura resultante não será opaca. Nenhuma das cores será completamente misturada.

Aninhando color-mix()

Como em todos os CSS, o aninhamento funciona bem e conforme esperado. as funções internas resolve primeiro e retorna seus valores para o contexto pai.

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

Sinta-se à vontade para aninhar o quanto precisar para chegar ao resultado desejado.

Como criar um esquema de cores claras e escuras

Vamos criar esquemas de cores com color-mix().

Um esquema de cores básico

No CSS a seguir, um tema claro e escuro são criados com base em um hexadecimal da marca cor O tema claro cria duas cores de texto azul escuro e um branco muito claro cor da superfície do plano de fundo. Em seguida, em uma consulta de mídia de preferência escura, a propriedades recebem novas cores para que o plano de fundo seja escuro e as cores do texto são leves.

: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);
  }
}

Tudo isso é conseguido com a mistura de branco e preto na cor da marca.

Esquema de cores intermediário

Para ir além, adicione mais do que os temas claro e escuro. Em na demonstração a seguir, mudanças no grupo de opções atualizam um atributo no HTML a tag [color-scheme="auto"], que permite que os seletores sejam aplicados condicionalmente um tema de cores.

(link em inglês)

Esta demonstração intermediária também mostra uma técnica de aplicação de temas de cores em que todas as as cores do tema estão listadas em :root. Isso facilita a visualização de todos eles e ajustar, se necessário. Mais adiante na folha de estilo, você pode usar as variáveis como são definido. Isso evita a busca pela folha de estilo para manipulações de cores, como eles estão todos no bloco :root inicial.

Casos de uso mais interessantes

Ana Tudor tem uma ótima demonstração com alguns casos de uso para o estudo:

Como depurar color-mix() com o DevTools

O Chrome DevTools tem um ótimo suporte para color-mix(). Ele reconhece e destaca a sintaxe, cria uma pré-visualização da mistura ao lado do estilo no painel Styles e permite escolher cores alternativas.

A aparência será semelhante a esta no DevTools:

Uma captura de tela do Chrome DevTools inspecionando a sintaxe da mistura de cores.

Aproveite, pessoal!