CSS color-mix()

Adam argyle
Adam Argyle

Com a função CSS color-mix(), você pode misturar cores em qualquer um dos espaços de cor aceitos diretamente do CSS.

Compatibilidade com navegadores

  • 111
  • 111
  • 113
  • 16.2

Origem

Antes de color-mix(), para escurecer, clarear ou dessaturar uma cor, os desenvolvedores usavam pré-processadores 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 por ficar à frente das especificações de cores de CSS. No entanto, não existe uma maneira real de misturar cores no CSS. Para chegar perto, você precisa fazer cálculos dos valores de cor parciais. Veja um exemplo reduzido de como o CSS pode simular a mixagem atualmente:

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

O color-mix() oferece a capacidade de misturar cores no CSS. Os desenvolvedores podem escolher o espaço de cores que vai misturar e o nível dominante de cada cor na combinação.

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 completas. Curta,

Como misturar cores no CSS

O CSS existe em um mundo com vários espaços e gama de cores e, por isso, não é opcional especificar o espaço de cores para mistura. Além disso, espaços de cores diferentes podem mudar drasticamente os resultados de uma combinação. Portanto, conhecer os efeitos de um espaço de cor ajuda 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). - Mude as cores que estão sendo mescladas clicando em uma das duas caixas de cores principais. - Use o controle deslizante para alterar a proporção de 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. Ele fornece resultados consistentes. Também é possível especificar espaços de cores alternativos para personalizar a combinação de acordo com suas necessidades.

Considere black e white, por exemplo. O espaço de cores que misturam não fará tanta 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 (srgb, linear-srgb, lch, oklch, lab, oklab, xyz) mostram os resultados da mistura de preto e branco. Cerca de cinco tons diferentes são mostrados, demonstrando que cada espaço de cor vai se misturar a um cinza de maneira diferente.
Confira a demonstração

Mas tem um grande efeito!

Use 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 roxa ao passar de branco para azul. Ele também mostra como oklab é um espaço de cores tão confiável para misturar e é 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 (srgb, linear-srgb, lch, oklch, lab, oklab, xyz) mostrados, cada um com resultados diferentes. Muitos são rosa ou roxos, 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 criar gradientes. A sintaxe da cor 4 também permite que os gradientes especifiquem o espaço de cores, em que um 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 espaços de cor diferentes.
Confira 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 mixagem 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 insaturadas.

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

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

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

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

Como ajustar o método de interpolação de matiz

Se você optou por misturar um espaço de cor cilíndrico, essencialmente, qualquer espaço de cor com um canal de matiz h que aceite um ângulo, poderá especificar se a interpolação vai ser shorter, longer, decreasing e increasing. Isso está bem abordado neste Guia de cores para HD se você quiser saber mais.

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

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

Veja aqui outro Codepen que fiz para ajudar a visualizar a interpolação de matizes, mas especificamente para gradientes. Acredito que isso vai ajudar você a entender como cada espaço de cores produz o resultado de mistura quando a interpolação de matiz é especificada. Preste atenção.

Mistura com sintaxes de cor variadas

Até agora, misturamos principalmente cores de nomes CSS, como blue e white. A mistura de cores CSS está pronta para misturar cores de dois espaços de cor diferentes. Esse é outro motivo pelo qual é fundamental especificar o espaço de cores 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, hsl e display-p3 serão convertidos em oklch e, em seguida, mistos. 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 todas as cores, como a maioria dos exemplos até agora mostrou. A boa notícia é que há uma sintaxe para articular quanto de cada cor precisa ser visto na mistura resultante.

Para começar este assunto, aqui está uma amostra de mixes que são todos 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%);
}

Esses exemplos esclarecem bem os casos extremos. O primeiro conjunto de exemplos mostra como 50% não é necessário, mas pode ser especificado opcionalmente. O último exemplo mostra um caso interessante em que, quando as proporções excedem 100% quando somadas, elas são igualmente limitadas a 100%.

Se apenas uma cor especificar uma proporção, a outra será considerada o restante para 100%. Confira mais alguns exemplos para ajudar a 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 */

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

A última regra é um pouco menos óbvia: o que acontecerá se porcentagens forem fornecidas para ambas as cores e elas não totalizarem 100%?

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

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

Aninhamento de color-mix()

Como tudo em CSS, o aninhamento é tratado bem e como esperado. As funções internas serão resolvidas primeiro e retornarão os valores delas ao contexto pai.

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

Fique à vontade para aninhar o quanto precisar para ter o resultado desejado.

Como criar um esquema de cores claras e escuras

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

Um esquema básico de cores

No CSS a seguir, um tema claro e escuro são criados com base em uma cor hexadecimal da marca. O tema claro cria duas cores de texto azul-escuro e uma cor de superfície branca muito clara de superfície. 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 claros.

: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 com a mistura de branco ou preto na cor da marca.

.

Esquema de cores intermediário

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

.

Esta demonstração intermediária também mostra uma técnica de aplicação de temas de cores em que todas as cores do tema são listadas em :root. Isso facilita a visualização e os ajustes necessários. Posteriormente, na folha de estilo, você pode usar as variáveis conforme elas são definidas. Isso economiza a busca por manipulações de cores na folha de estilo, já que todas 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:

Como depurar color-mix() com o DevTools

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

Ele vai ficar mais ou menos assim no DevTools:

Captura de tela do Chrome DevTools inspecionando a sintaxe de mistura de cores.

Divirta-se criando!