Crie novas cores com base nos canais e valores de outra cor.
No Chrome 119, há um recurso de cor muito poderoso do CSS Color Level 5. A sintaxe de cor relativa cria um caminho suave para a manipulação de cores no CSS, oferecendo maneiras de autores e designers:
- Iluminar
- Escurecer
- Saturação
- Desaturar
- Chroma boost
- Ajustar a opacidade
- Inverter
- Complementar
- Converter
- Contraste
- Paleta de cores
Antes da sintaxe de cor relativa, para modificar a opacidade de uma cor, é necessário criar propriedades personalizadas para os canais de uma cor, geralmente HSL, e montá-las em uma cor final e uma cor de variante final. Isso significa gerenciar muitas peças coloridas, o que pode se tornar uma tarefa pesada.
:root {
--brand-hue: 300deg;
--brand-saturation: 75%;
--brand-lightness: 50%;
--brand-hsl:
var(--brand-hue)
var(--brand-saturation)
var(--brand-lightness);
--brand-color: hsl(var(--brand-hsl));
/* all this work just so I can set the opacity to 50% in a variant */
--brand-color-variant: hsl(var(--brand-hsl) / 50%);
}
Depois da sintaxe de cor relativa, você pode criar uma cor de marca com qualquer espaço de cor ou sintaxe necessária e criar uma variante de meia opacidade com muito menos código. Também fica muito mais fácil ler a intenção dos estilos e do sistema.
:root {
--brand-color: hsl(300deg 75% 50%);
--brand-color-variant: hsl(from var(--brand-color) h s l / 50%);
}
Esta postagem vai ajudar você a aprender a sintaxe e demonstrar manipulações de cores comuns.
Se você preferir vídeos, quase todos os artigos a seguir são abordados neste desafio de GUI.
Visão geral da sintaxe
O objetivo da sintaxe de cores relativa é permitir a derivação de uma cor de outra
cor. A cor base é chamada de cor de origem, que é a cor que
vem depois da nova palavra-chave from
. O navegador
converte e separa essa cor de origem, oferecendo
as partes como variáveis para uso na nova definição de cor.
O diagrama anterior mostra a cor de origem green
sendo convertida para o
espaço de cor da nova cor,
transformada em números individuais representados como variáveis r
, g
, b
e alpha
,
que são usadas diretamente como novos valores de cor rgb()
.
Embora essa imagem mostre a divisão, o processo e as variáveis, ela também não muda a cor. As variáveis são recolocadas na cor inalterada, resultando em uma cor verde.
A palavra-chave from
A primeira parte da sintaxe a ser aprendida é a adição de from <color>
para
especificar uma cor. Ele é exibido antes de você especificar os valores. Confira um exemplo de código
em que tudo o que foi adicionado é from green
, logo antes de os valores
de rgb()
serem especificados.
.syntax-introduction_same-colors {
color: green;
color: rgb(0 128 0);
color: rgb(from green r g b); /* result = rgb(0 128 0) */
}
Essa palavra-chave from
, quando vista como o primeiro parâmetro na notação funcional, transforma a definição de cor em uma cor relativa. Depois da palavra-chave from
, o CSS
espera uma cor, uma cor que vai inspirar a próxima cor.
Conversão de cores
Em termos mais simples, ele converte o verde em canais "r g" e "b" para usar em uma nova cor.
rgb(from green r g b) /* r=0 g=128 b=0 */
rgb(from rgb(0 128 0) r g b); /* r=0 g=128 b=0 */
Cores de propriedades personalizadas
A leitura de rgb from green
é muito clara e fácil de entender. É por isso que
propriedades personalizadas e sintaxe de cor relativa são uma combinação tão boa, porque você
pode descobrir a cor from
. Também não é necessário
conhecer o formato de cor da propriedade personalizada, já que você está criando uma nova
cor no formato que preferir.
rgb(from rgb(255 105 180) r g b) /* ????? */
rgb(from var(--hotpink) r g b) /* clear */
Trabalhar no espaço de cores de sua preferência
Você pode escolher o espaço de cores com a notação de cor funcional que preferir.
rgb(from hsl(120 100% 25%) r g b) /* r=0 g=128 b=0 */
hsl(from hsl(120 100% 25%) h s l) /* h=120 s=100% l=25% */
hwb(from hsl(120 100% 25%) h w b) /* h=120 w=0% b=50% */
lch(from hsl(120 100% 25%) l c h) /* l=46 c=68 h=134 */
A sintaxe de cor relativa tem essa etapa de conversão. A cor após from
é
convertida no espaço de cores conforme especificado no início da cor
relativa. A entrada e a saída não precisam ser iguais, o que é muito libertador.
A capacidade de escolher um espaço de cores também é capacitadora, já que a escolha de um espaço de cores tende a se concentrar mais no tipo de alternância de cores do que em uma preferência. A preferência está nos resultados, não no formato de cor ou nos tipos de canal. Isso ficará muito mais claro nas seções que demonstram casos de uso, já que espaços de cor diferentes se destacam em tarefas distintas.
Misture, combine, omita e repita as variáveis
Algo estranho, mas interessante nessa sintaxe, as variáveis não precisam ser colocadas de volta na ordem e podem ser repetidas.
rgb(from green g g g) /* rgb(128 128 128) */
rgb(from green b r g) /* rgb(0 0 128) */
rgb(from green 0 0 g) /* rgb(0 0 128) */
Opacidade como uma variável
A sintaxe também fornece a opacidade como uma variável chamada alpha
. Ela é opcional
e fica depois do /
na notação funcional de cores.
rgb(from #00800080 r g b / alpha) /* alpha=50% */
rgb(from rgba(0,128,0,.5) r g b / alpha) /* alpha=50% */
rgb(from rgb(0 128 0 / 50%) r g b / alpha) /* alpha=50% */
Use calc() ou outras funções CSS nas variáveis
Até agora, criamos a cor verde várias vezes. Aprender a sintaxe, conhecer as etapas de conversão e de desestruturação. Agora é hora de modificar as variáveis, alterando a saída para que ela não seja igual à entrada.
green /* h=120 s=100% l=25% */
hsl(from green calc(h * 2) s l) /* h=240 s=100% l=25% */
Agora é azul-marinho! A tonalidade foi duplicada, pegando uma tonalidade de 120
e a transformando em
240
, mudando completamente a cor. Isso fez com que a matiz girasse ao longo da roda de
cores, um truque simples com espaços de cores cilíndricos
como HSL,
HWB,
LCH e
OKLCH.
Para conferir visualmente os valores dos canais e fazer os cálculos sem precisar adivinhar ou memorizar as especificações, use esta ferramenta de valores de canal de sintaxe de cor relativa. Ele revela o valor de cada canal com base na sintaxe especificada, permitindo que você saiba exatamente quais valores estão disponíveis para usar.
Verificar o suporte do navegador
@supports (color: rgb(from white r g b)) {
/* safe to use relative color syntax */
}
Casos de uso e demonstrações
Os exemplos e casos de uso abaixo têm muitas sintaxes alternativas para conseguir resultados semelhantes ou iguais. As variações vêm dos espaços de cor e dos canais que eles oferecem.
Além disso, muitos exemplos mostram ajustes de cor com a linguagem de by
e
to
. Uma cor alterada by
é uma mudança de cor relativa, uma mudança que usa o
valor da variável e faz um ajuste com base no valor atual. Uma
mudança de cor to
é uma mudança de cor absoluta, uma mudança que não usa o
valor da variável e especifica um valor completamente novo.
Todas as demonstrações podem ser encontradas nesta coleção do Codepen.
Clarear uma cor
Os espaços de cor OKLCH, OKLAB, XYZ ou sRGB oferecem os resultados mais previsíveis ao clarear cores.
Diminuir bastante
O exemplo .lighten-by-25
a seguir converte a cor blue
em
OKLCH e, em seguida, clareia o azul aumentando o canal l
(luminosidade) multiplicando
o valor atual por 1.25
. Isso aumenta a luminosidade azul em 25% em relação ao branco.
.lighten-by-25 {
background: oklch(from blue calc(l * 1.25) c h);
}
Clarear para um valor específico
O exemplo .lighten-to-75
a seguir não utiliza o canal l
para
clarear blue
, mas substitui completamente o valor por 75%
.
.lighten-to-75 {
background: oklch(from blue 75% c h);
}
Escurecer uma cor
Os mesmos espaços de cores que clareiam uma cor também são ótimos para escurecer.
Escurecer por um valor
O exemplo a seguir .darken-by-25
usa a cor azul e a converte em
OKLCH e, em seguida, escurece o azul diminuindo o canal l
(iluminação) em 25% multiplicando o valor por .75
. Isso empurra a cor azul para o preto em 25%.
.darken-by-25 {
background: oklch(from blue calc(l * .75) c h);
}
Escurecer para um valor especificado
O exemplo .darken-to-25
a seguir não utiliza o canal l
para escurecer
blue
, mas substitui completamente o valor por 25%
.
.darken-to-25 {
background: oklch(from blue 25% c h);
}
Saturar uma cor
Saturar por um valor
O exemplo de .saturate-by-50
a seguir usa o s
de hsl()
para aumentar
a vibração de orchid
por um 50%
relativo.
.saturate-by-50 {
background: hsl(from orchid h calc(s * 1.5) l);
}
Saturar até um valor específico
O exemplo de .saturate-to-100
a seguir não utiliza o canal s
de
hsl()
, mas especifica um valor de saturação desejado. Neste exemplo,
a saturação é aumentada para 100%
.
.saturate-to-100 {
background: hsl(from orchid h 100% l);
}
Desaturar uma cor
Desaturar por um valor
O exemplo .desaturate-by-half
a seguir usa o s
de hsl()
para reduzir
a saturação de indigo
pela metade.
.desaturate-by-half {
background: hsl(from indigo h calc(s / 2) l);
}
Desaturar para um valor específico
Em vez de desaturar por uma quantidade, você pode desaturar para um valor
específico. O exemplo .desaturate-to-25
a seguir cria uma nova cor com base em
indigo
, mas define a saturação como 25%.
.desaturate-to-25 {
background: hsl(from indigo h 25% l);
}
Realce de cor
Esse efeito é semelhante à saturação de uma cor, mas é diferente em alguns
aspectos. Em primeiro lugar, é uma mudança de chroma
, e não de saturation
,
porque os espaços de cores que podem aumentar o alcance dinâmico não usam
saturação. Os espaços de cor que apresentam chroma
são capazes de alto alcance dinâmico, permitindo que os autores aumentem a vibração de cores ainda mais do que a saturação.
.increase-chroma {
background: oklch(from orange l calc(c + .1) h);
}
Ajustar a opacidade de uma cor
Criar uma variante semitransparente de uma cor é um dos ajustes de cor mais comuns feitos em sistemas de design. Confira o exemplo na introdução deste artigo, se você não o encontrou, ele descreve o espaço do problema muito bem.
Ajustar a opacidade por um valor
.decrease-opacity-by-25 {
background: rgb(from lime r g b / calc(alpha / 2));
}
Ajustar a opacidade para um valor específico
.decrease-opacity-to-25 {
background: rgb(from lime r g b / 25%);
}
Inverter uma cor
A inversão de cores é uma função comum de ajuste de cores encontrada em bibliotecas de cores. Uma maneira de fazer isso é converter uma cor em RGB e, em seguida, subtrair o valor de cada canal de 1.
.invert-each-rgb-channel {
background: rgb(from yellow calc(255 - r) calc(255 - g) calc(255 - b));
}
Complementar uma cor
Se sua meta não era inverter uma cor, mas complementá-la, a rotação
de matiz provavelmente é o que você está procurando. Escolha um espaço de cores que ofereça a
cor como um ângulo e use calc()
para girar a cor pelo valor que quiser.
A busca do complemento de uma cor é feita girando metade de uma volta. Nesse caso, é possível adicionar ou subtrair do canal h
por 180
para alcançar o resultado.
.complementary-color {
background: hsl(from blue calc(h + 180) s l);
}
Contrastar uma cor
Como um método para alcançar proporções de contraste de cores acessíveis, considere L* (Lstar).
Isso usa o canal de luminosidade (L) perceptualmente uniforme (aproximadamente) de
LCH e OKLCH, em um calc()
. Dependendo se você está segmentando contraste baixo, médio ou alto, a delta de L* é de aproximadamente 40, 50 ou 60.
Essa técnica funciona bem com qualquer tonalidade em LCH ou OKLCH.
Contrastar uma cor mais escura
A classe .well-contrasting-darker-color
demonstra L* com um delta de 60.
Como a cor de origem é escura (valor de luminosidade baixo), 60% (0,6) é adicionado
ao canal de luminosidade. Essa técnica é usada para encontrar uma cor de texto escura bem contrastante
com a mesma matiz em um plano de fundo claro.
.well-contrasting-darker-color {
background: darkred;
color: oklch(from darkred calc(l + .60) c h);
}
Contrastar uma cor mais clara
A classe .well-contrasting-lighter-color
também demonstra L* com um delta de 60%. Como a cor de origem é uma cor clara (brilho de alto valor), 0,60 é
subtraído do canal de brilho.
.well-contrasting-lighter-color {
background: lightpink;
color: oklch(from lightpink calc(l - .60) c h);
}
Paletas de cores
A sintaxe de cores relativa é muito boa para criar paletas de cores. Ela é especialmente útil e poderosa devido ao número de espaços de cores disponíveis. Os exemplos a seguir usam o OKLCH porque o canal de luminosidade é confiável e o canal de matiz pode ser girado sem efeitos colaterais. O exemplo final demonstra uma combinação de ajustes de claridade e rotação de matiz para gerar um resultado mais interessante.
Abra o código-fonte de exemplo para essas paletas e tente mudar o --base-color
para
ver como elas são dinâmicas. É divertido!
Se você gosta de vídeos, confira informações detalhadas sobre como criar paletas de cores no CSS com OKLCH no YouTube.
Paletas monocromáticas
Criar uma paleta monocromática é fazer uma paleta da mesma tonalidade, mas com variações de claridade e escuridão. A cor do meio é a cor de origem da paleta, em que duas variantes mais claras e duas mais escuras são colocadas em cada lado.
:root {
--base-color: deeppink;
--color-0: oklch(from var(--base-color) calc(l + .20) c h); /* lightest */
--color-1: oklch(from var(--base-color) calc(l + .10) c h);
--color-2: var(--base-color);
--color-3: oklch(from var(--base-color) calc(l - .10) c h);
--color-4: oklch(from var(--base-color) calc(l - .20) c h); /* darkest */
}
Teste várias paletas criadas com sintaxe de cores relativa e OKLCH
O Open Props, uma biblioteca de variáveis CSS sem custo financeiro, oferece paletas de cores criadas com essa estratégia e as torna facilmente utilizáveis com uma importação. Eles também são todos criados com uma cor que você pode personalizar: basta dar uma cor e gerar uma paleta.
Paletas análogas
Como a rotação de matiz é tão fácil com OKLCH e HSL, é trivial criar uma paleta de cores análoga. Gire a matiz em uma quantidade que você goste dos resultados e mude a cor de base. Observe as novas paletas sendo criadas pelo navegador.
:root {
--base-color: blue;
--primary: var(--base-color);
--secondary: oklch(from var(--base-color) l c calc(h - 45));
--tertiary: oklch(from var(--base-color) l c calc(h + 45));
}
Paletas triádicas
Semelhantes às cores complementares, as paletas de cores triádicas
são rotações de matiz opostas, mas harmoniosas, dadas uma cor de base. Quando uma
cor complementar está no lado oposto de uma cor, como uma linha reta
desenhada no meio da roda de cores, as paletas triádicas são como um
triângulo de linhas, encontrando duas cores igualmente giradas de uma cor base.
Para fazer isso, gire a matiz 120deg
.
Essa é uma simplificação da teoria das cores, mas é suficiente para você começar a usar as paletas triádicas mais complexas, se quiser.
:root {
--base-color: yellow;
--triad-1: oklch(from var(--base-color) l c calc(h - 120));
--triad-2: oklch(from var(--base-color) l c calc(h + 120));
}
Paletas Tetradic
As paletas tetradísticas são quatro cores divididas igualmente ao redor da roda de cores, criando uma paleta sem um valor dominante claro. Você também pode pensar nisso como dois pares de cores complementares. Se usado com sabedoria, pode ser muito significativo.
Essa é uma pequena simplificação da teoria das cores, mas é o suficiente para começar a usar paletas de cores mais complexas, se tiver interesse.
:root {
--base-color: lime;
--color-1: var(--base-color);
--color-2: oklch(from var(--base-color) l c calc(h + 90));
--color-3: oklch(from var(--base-color) l c calc(h + 180));
--color-4: oklch(from var(--base-color) l c calc(h + 270));
}
Monocromático com uma leve rotação de matiz
Muitos especialistas em cores guardam esse truque na manga. O problema é que uma escala de cores monocromática pode ser bastante chata. A solução é adicionar uma rotação de matiz menor ou maior a cada nova cor à medida que a luminosidade é alterada.
O exemplo a seguir diminui a luminosidade em 10% em cada amostra e também gira a matiz em 10 graus. O resultado é uma paleta de cores quentes a índigo que parece se misturar perfeitamente como um gradiente.
:root {
--base-color: deeppink;
--color-1: var(--base-color);
--color-2: oklch(from var(--base-color) calc(l - .10) c calc(h - 10));
--color-3: oklch(from var(--base-color) calc(l - .20) c calc(h - 20));
--color-4: oklch(from var(--base-color) calc(l - .30) c calc(h - 30));
--color-5: oklch(from var(--base-color) calc(l - .40) c calc(h - 40));
}
Teste este placar criado com OKLCH e rotação de matiz
A interface da tabela de classificação a seguir usa essa estratégia de rotação de matiz. Cada item
da lista rastreia o índice no documento como uma variável chamada --i
. Esse índice é
usado para ajustar a croma, a luminosidade e a matiz. O ajuste é de apenas 5% ou
5 graus, muito mais sutil do que o exemplo acima com deeppink. Portanto, é preciso ter
bom senso para notar o motivo pelo qual essa tabela de classificação pode estar em qualquer matiz com tanta
elegância.
Mude a matiz no controle deslizante abaixo da tabela de classificação e veja a sintaxe de cores relativa criar momentos de cores incríveis.
li {
--_bg: oklch(
/* decrease lightness as list grows */
calc(75% - (var(--i) * 5%))
/* decrease chroma as list grows */
calc(.2 - (var(--i) * .01))
/* lightly rotate the hue as the list grows */
calc(var(--hue) - (var(--i) + 5))
);
}