A função color-mix()
(link em inglês)
de CSS permite misturar cores em qualquer um dos espaços de cores compatíveis diretamente do CSS.
Antes de color-mix()
, para escurecer, clarear ou diminuir a saturação de uma cor, os desenvolvedores usavam
pré-processadores CSS ou
calc()
em canais de
cores.
.color-mixing-with-sass { /* Sass: equally mix red with white */ --red-white-mix: color.mix(red, white); }
A Sass fez um ótimo trabalho para ficar à frente das especificações de cores do CSS. Entretanto, 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 uma mistura atualmente:
.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()
traz a
capacidade de misturar cores ao CSS. Os desenvolvedores podem escolher o espaço de cores que vão misturar
e o nível de dominante de cada cor na combinação.
.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 de vários espaços de cores e uma gama de cores e, por isso, não é opcional especificar o espaço de cores para mistura. Além disso, diferentes espaços de cores podem mudar drasticamente os resultados de uma mistura. Portanto, conhecer os efeitos de um espaço de cor ajuda você a conseguir os resultados necessários.
Para uma introdução interativa, use esta ferramenta color-mix()
:
- Explore os efeitos de cada espaço de cor.
- Explorar os efeitos de interpolação de matiz ao fazer a mistura em um espaço de cores cilíndrico (lch
, oklch
, hsl
e hwb
).
- Para mudar as cores que estão sendo misturadas, clique em uma das duas caixas de cores superiores.
- 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
mix de acordo com suas necessidades.
Por exemplo, considere black
e white
. O espaço de cores que elas se 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);
Essa ação tem um efeito incrível!
Use blue
e white
para outro exemplo. Escolhi essa opção 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 roxo enquanto passa do branco para o azul. Ele
também mostra como oklab
é um espaço de cores tão confiável para combinação, que
é 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);
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 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);
}
Se você está se perguntando qual espaço de cor é "o melhor", não existe um. É por isso
que existem 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 combinadas, e hsl e hwb produzem um resultado vibrante, enquanto srgb e oklab produzem cores insaturadas.
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 matiz alteradas, enquanto srgb e oklab produzem um azul mais escuro.
Passe cinco minutos com o color-mix()
playground testando diferentes cores
e espaços para começar a conhecer as vantagens de cada espaço. Além disso,
esperamos que aconteça mais orientações sobre os espaços de cores, à medida que nos ajustamos aos
potenciais 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, será possível especificar se a
interpolação vai ser shorter
, longer
, decreasing
e increasing
. Se você quiser saber mais, isso
é bem abordado neste Guia de cores HD.
Confira 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.
Aqui está 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 espaço de cores produz o resultado de mistura quando a interpolação de matiz é especificada, faça um estudo.
Mistura com sintaxes de cores 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 cores 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, misturados. Muito legal e flexível.
Como ajustar as proporções de mistura
Não é muito provável que você queira partes iguais de cada cor toda vez que misturar, como a maioria dos exemplos até agora mostrou. A boa notícia é que existe uma sintaxe para articular quanto de cada cor precisa ser vista na mistura resultante.
Para começar este tópico, 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%);
}
Acho que esses exemplos ajudam a esclarecer 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 em que, quando as proporções excedem 100% quando somadas, elas são igualmente fixadas no total de 100%.
Observe também que, se apenas uma cor especificar uma proporção, a outra será considerada o restante de 100%. Aqui estão 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 */
Esses 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 acontece se as porcentagens forem fornecidas para ambas as cores e 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 será opaca.
Nenhuma das cores será totalmente misturada.
Conjunto de color-mix()
Como em todo o CSS, o aninhamento é processado 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 for necessário para alcançar o resultado desejado.
Como criar um esquema de cores claras e escuras
Vamos criar esquemas de cores com o color-mix()
.
Um esquema de cores básico
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 na 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 mais 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 ao misturar branco ou preto em uma cor de marca.
Esquema de cores intermediário
Isso pode ser feito 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"]
, que permite que os seletores apliquem
condicionalmente um tema de cores.
Essa 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 de todos e
os ajustes, se necessário. Mais adiante 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 DevTools
O Chrome DevTools tem excelente suporte para color-mix()
. Ele reconhece e
destaca a sintaxe, cria uma prévia da combinação ao lado do estilo no
painel "Styles" e permite escolher cores alternativas.
Ela vai ficar mais ou menos assim no DevTools:
Divirta-se!