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ídeo, quase todo o artigo a seguir é abordado 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 colocadas de volta na cor sem alterações, 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 considerada 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 uso 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 corresponder, o que é muito libertador.
A capacidade de escolher um espaço de cores também é importante, já que a escolha de um espaço de cores tende a ser mais focada 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 vai ficar muito mais claro nas seções que demonstram casos de uso, já que espaços de cores diferentes se destacam em tarefas diferentes.
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! O matiz foi duplicado, transformando um matiz de 120
em
240
, alterando 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.
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 a seguir têm muitas sintaxe alternativas para alcançar 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.
Iluminar uma cor
Os espaços de cor OKLCH, OKLAB, XYZ ou sRGB oferecem os resultados mais previsíveis ao clarear cores.
Diminuir por um valor
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);
}
Iluminar 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 .darken-by-25
a seguir converte a cor azul em
OKLCH e, em seguida, escurece o azul diminuindo o canal l
(luminosidade) em 25% ao multiplicar o valor por .75
. Isso empurra a cor azul em direção ao 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 é elevada 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 cores que têm chroma
são compatíveis com o alto alcance dinâmico, permitindo que os autores aumentem a vibração das cores além do que a saturação
permite.
.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 de ajuste de cor comum encontrada nas bibliotecas de cores. Uma maneira de fazer isso é converter uma cor em RGB e 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 sim 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 você 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 em qualquer matiz 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 é clara (valor alto de luminosidade), 0,60 é
subtraído do canal de luminosidade.
.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 rotação de luminosidade e matiz para 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 é criar uma paleta com a 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 criados com uma cor que você pode personalizar. Basta fornecer uma cor para gerar uma paleta.
Paletas análogas
Como a rotação de matiz é muito fácil com OKLCH e HSL, é muito simples criar uma paleta de cores análogas. Gire a matiz em uma quantidade que você goste dos resultados e mude a cor de base. Observe como novas paletas são 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 a partir 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 tetradicas
As paletas tetradêmicas 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 simplificação da teoria das cores, mas é suficiente para você começar a usar as paletas tetradas mais complexas, se quiser.
: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ática com uma ligeira 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 hot pink 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 por que essa tabela de classificação pode estar em qualquer matiz com tanta
elegância.
Mude a tonalidade 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))
);
}