CSS color-mix()

A função color-mix() do CSS permite misturar cores em qualquer um dos espaços de cor compatíveis diretamente do CSS.

Browser Support

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

Source

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

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

Sass fez um ótimo trabalho ao ficar à frente da especificação de cores do CSS. No entanto, não havia uma maneira real de misturar cores no CSS. Para se aproximar, é necessário fazer cálculos de valores de cores parciais. Confira um exemplo reduzido de como o CSS pode simular a mistura 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 capacidade de misturar cores para CSS. Os desenvolvedores podem escolher em qual espaço de cor eles misturam e o quão dominante cada cor deve ser 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, potência e APIs com todos os recursos. A paixão é sua.

Misturar cores no CSS

O CSS existe em um mundo de vários espaços de cor e gamas de cores e, por isso, não é opcional especificar o espaço de cor para mistura. Além disso, espaços de cor diferentes podem mudar drasticamente os resultados de uma mistura. Portanto, conhecer os efeitos de um espaço de cor vai ajudar você a conseguir os resultados necessários.

Para uma introdução interativa, teste esta ferramenta color-mix(): - Explore os efeitos de cada espaço de cor. - Explore os efeitos da interpolação de matiz ao misturar em um espaço de cor cilíndrico (lch, oklch, hsl, e hwb).- Clique em uma das duas caixas de cor na parte de cima para mudar as cores que estão sendo misturadas. - Use o controle deslizante para mudar a proporção de mistura. - O código CSS color-mix() gerado está disponível na parte de baixo.

Misturar nos vários espaços de cor

O espaço de cor padrão para mistura (e gradientes) é oklab. Ele fornece resultados consistentes. Você também pode especificar espaços de cor alternativos para adaptar a mistura às suas necessidades.

Por exemplo, black e white. O espaço de cor em que eles se misturam não faz muita 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 cores (srgb, linear-srgb, 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 mistura de maneira diferente até chegar ao cinza.
Teste a demonstração

Ele tem um grande efeito.

Considere 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, a maioria dos espaços de cor fica roxa ao viajar do branco para o azul. Ele também mostra como oklab é um espaço de cor confiável para mistura, sendo 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);
7 espaços de cores (srgb, linear-srgb, lch, oklch, lab, oklab, xyz), cada um mostrando resultados diferentes. Muitas são rosa ou roxas, e poucas ainda são azuis.
Teste a demonstração

Aprender os efeitos de um espaço de cor com color-mix() também é um ótimo conhecimento para criar gradientes too. A sintaxe de cor 4 também permite que os gradientes especifiquem o espaço de cor, em que um gradiente mostra a mistura em 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 para branco em diferentes espaços de cores.
Teste a demonstração

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

Por exemplo, se você quiser um resultado de mistura vibrante, use hsl ou hwb. Na demonstração a seguir, duas cores vibrantes (magenta e limão) são misturadas, e hsl e hwb produzem um resultado vibrante, enquanto srgb e oklab produzem cores não saturadas.

A combinação resulta no que foi descrito no parágrafo anterior.
Teste a demonstração

Se você quiser consistência e sutileza, use oklab. Na demonstração a seguir, que mistura azul e preto, hsl e hwb produzem cores excessivamente vibrantes e com matiz alterado, enquanto srgb e oklab produzem um azul mais escuro.

A combinação resulta no que foi descrito no parágrafo anterior.
Teste a demonstração

Passe cinco minutos com o color-mix() playground, testando cores e espaços diferentes, e você vai começar a sentir as vantagens de cada espaço. Também espere mais orientações sobre espaços de cor à medida que todos nos ajustamos aos potenciais deles nas interfaces do usuário.

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

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

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

A combinação resulta no que foi descrito no parágrafo anterior.
Teste a demonstração

Aqui está outro Codepen que criei para ajudar a visualizar a interpolação de matiz, mas especificamente para gradientes. Acredito que isso vai ajudar você a entender como cada espaço de cor produz o resultado da mistura quando a interpolação de matiz é especificada. Faça um estudo.

Misturar com sintaxes de cores variadas

Até agora, misturamos principalmente cores nomeadas do CSS, como blue e white. A mistura de cores do CSS está pronta para misturar cores de dois espaços de cor diferentes. Esse é outro motivo pelo qual é fundamental especificar o espaço de cor para a mistura, já que ele 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, o hsl e o display-p3 serão convertidos em oklch e misturados. Muito legal e flexível.

Ajustar as proporções de mistura

Não é muito provável que toda vez que você misture, queira partes iguais de cada cor, como a maioria dos exemplos até agora mostrou. Boas notícias: há uma sintaxe para articular a quantidade de cada cor que deve ser vista na mistura resultante.

Para começar este tópico, confira uma amostra de misturas equivalentes (e da especificação):

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

Acho que esses exemplos iluminam bem os casos extremos. O primeiro conjunto de exemplos mostra como 50% não é obrigatório, mas pode ser especificado opcionalmente. O último exemplo mostra um caso interessante para quando as proporções excedem 100% quando adicionadas juntas, elas são igualmente fixadas para totalizar 100%.

Observe também que, se apenas uma cor especificar uma proporção, a outra será considerada o restante até 100%. Confira mais alguns exemplos para ilustrar esse comportamento.

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 fixadas 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 as duas cores e não somarem 100%?

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

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

Aninhar color-mix()

Como todo o CSS, o aninhamento é processado bem e conforme o esperado. As funções internas serão resolvidas primeiro e retornarão os valores ao contexto pai.

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

Fique à vontade para aninhar o quanto precisar para chegar ao resultado desejado.

Criar um esquema de cores claro e escuro

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

Um esquema de cores básico

No CSS a seguir, um tema claro e escuro é criado com base em uma cor hexadecimal da marca. O tema claro cria duas cores de texto azul-escuras e uma cor de superfície de fundo branca muito clara. Em seguida, em uma consulta de mídia de preferência escura, as propriedades personalizadas recebem novas cores para que o plano de fundo seja escuro e as cores do texto sejam claras.

: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 é feito misturando branco ou preto em uma cor da marca.

Esquema de cores intermediário

Isso pode ser levado um passo adiante adicionando mais temas claros e escuros. Na demonstração a seguir, as mudanças no grupo de botões de opção atualizam um atributo na tag HTML [color-scheme="auto"], que permite que os seletores apliquem condicionalmente um tema de cores.

Essa demonstração intermediária também mostra uma técnica de tema de cores em que todas as cores do tema são listadas em :root. Isso facilita a visualização de todas elas juntas e o ajuste, se necessário. Mais tarde na folha de estilo, você pode usar as variáveis conforme elas são definidas. Isso evita a necessidade de procurar na folha de estilo manipulações de cores, já que elas estão contidas no bloco :root inicial.

Casos de uso mais interessantes

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

Depurar color-mix() com o DevTools

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

Ele será parecido com isto no DevTools:

O Chrome DevTools inspeciona a sintaxe color-mix.

Boa mistura a todos!