Sintaxe de cores relativa de CSS

Cria novas cores com base nos canais e valores de outra cor.

Adam Argyle
Adam Argyle

No Chrome 119, há um recurso de cores muito poderoso do CSS Color Level 5 (link em inglês). Sintaxe de cor relativa cria um caminho suave para a manipulação de cores dentro do CSS, oferecendo maneiras autores e designers para:

Antes da sintaxe de cores relativas, para modificar a opacidade de uma cor, é necessário criar propriedades personalizadas para os canais de uma cor, normalmente HSL, e montar em uma cor final e cor da variante final. Isso significa gerenciar muitos pedaços de cor, que podem se tornar rapidamente incômodos.

: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 cores. ou a sintaxe que você precisa e crie uma variante de meia opacidade com muito menos código. Está muito mais fácil de 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 todos os artigos a seguir são abordados neste desafio de GUI.

Visão geral da sintaxe

O objetivo da sintaxe de cor relativa é permitir a derivação de uma cor de outra cor A cor de base é chamada de cor de origem, ou seja, a cor que vem depois da nova palavra-chave from. O navegador converter e separar a cor de origem e oferecer as partes como variáveis para uso na nova definição de cor.

Um
Diagrama da sintaxe rgb(de verde r g b / alfa) com uma seta
deixando a parte superior do verde e arqueando o começo da função rgb,
a seta se divide em 4 setas que apontam para a variável relevante. A
Quatro setas são vermelha, verde, azul e alfa. Vermelho e azul têm um valor de 0, e verde
é 128 e alfa é 100%.

O diagrama anterior mostra a cor de origem green sendo convertida para a o espaço de cores de nova cor, transformados em números individuais representados como r, g, b e alpha variáveis, que são usadas diretamente como valores de uma nova cor rgb().

A imagem mostra o detalhamento, o processo e as variáveis, mas não mudando a cor. As variáveis são recolocadas de volta na cor inalterada, assim resultando em uma cor verde.

A palavra-chave from

A primeira parte da sintaxe a ser aprendida é a parte from <color>, além da especificando uma cor. Ela ocorre imediatamente antes de você especificar os valores. Aqui está um código exemplo em que tudo foi adicionado é from green, logo antes dos valores para rgb() forem especificadas.

.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 da cor em uma cor relativa! Após a palavra-chave from, o CSS espera uma cor, uma cor que vai inspirar a próxima cor.

Conversão de cor

Em termos mais simples, ele converte o verde em "r g" e os canais "b" para uso em um novo 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 as propriedades personalizadas e a sintaxe de cor relativa fazem uma ótima correspondência, porque você pode eliminar o mistério da cor from. Você também geralmente não precisa saber o formato de cor da cor da propriedade personalizada, ao criar uma nova cor no formato de sua escolha.

rgb(from rgb(255 105 180) r g b) /* ????? */
rgb(from var(--hotpink) r g b)   /* clear */

Trabalhe no seu espaço de cores preferido.

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 é convertido no espaço de cores, conforme especificado no início da cor 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, porque escolher uma cor tende a se concentrar mais no tipo de alternância de cores do que em uma preferência. A preferência está nos resultados, e não no formato de cor ou canal tipos Isso ficará muito mais claro nas seções que demonstram casos de uso, como diferentes espaços de cor se destacam em diferentes tarefas.

Misturar, combinar, omitir e repetir as variáveis

Algo estranho, mas interessante sobre essa sintaxe, as variáveis não precisam ser colocar de novo em ordem e pode ser repetido.

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 com o nome alpha. Ele é opcional, e vai depois de / na notação de cor funcional.

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% */

Usar calc() ou outras funções CSS nas variáveis

Até agora, criamos a cor verde repetidamente. Aprender a e se familiarize com as etapas de conversão e desestruturação. Agora é modificar as variáveis, alterar a saída para que 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 120 e a transformando em 240, mudando completamente a cor. Isso girou a tonalidade ao longo da cor roda, um truque interessante e muito simples com espaços de cor cilíndricos. como o HSL, HWB, LCH e OKLCH.

Para conferir visualmente os valores dos canais e fazer a matemática corretamente sem adivinhar e memorizar a especificação, teste a 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.

Conferir se o navegador é compatível

@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 sintaxes alternativas a serem alcançadas resultados semelhantes ou iguais. As variações vêm dos espaços de cores e e os canais que elas oferecem.

Além disso, muitos exemplos mostram ajustes de cor com o uso de by e to. Uma cor alterada by é uma mudança de cor relativa. uma mudança que usa valor da variável e faz um ajuste com base em seu valor atual. Um cor alterada to é uma mudança de cor absoluta. uma mudança que não usa valor da variável e, em vez disso, especifica um valor completamente novo.

Todas as demonstrações podem ser encontradas nesta coleção do Codepen.

Clarear uma cor

O OKLCH, OKLAB, XYZ ou Os espaços de cor sRGB oferecem o maior resultados previsíveis ao diminuir as cores.

Diminuir bastante

O exemplo a seguir .lighten-by-25 usa a cor blue e a converte em OKLCH, depois clareia o azul aumentando o canal l (iluminação) multiplicando o valor atual por 1.25. Isso empurra a claridade azul para o branco em 25%.

.lighten-by-25 {
  background: oklch(from blue calc(l * 1.25) c h);
}

Clarear para um valor específico

O exemplo a seguir .lighten-to-75 não usa o canal l para clarear blue, ela vai substituir completamente o valor por 75%.

.lighten-to-75 {
  background: oklch(from blue 75% c h);
}

Escurecer uma cor

Os mesmos espaços de cor, eficazes para clarear uma cor, também são ótimos para cor escurecida.

Escurecer um nível

O exemplo a seguir .darken-by-25 usa a cor azul e a converte em OKLCH, depois escurece o azul diminuindo o canal l (clareza) em 25% em 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 até um valor especificado

O exemplo de .darken-to-25 abaixo não usa o canal l para escurecer blue, ela substitui completamente o valor por 25%.

.darken-to-25 {
  background: oklch(from blue 25% c h);
}
(link em inglês)

Saturar uma cor

Saturar em um valor

O exemplo a seguir .saturate-by-50 usa o s de hsl() para aumentar Vibração de orchid por um 50% relativo.

.saturate-by-50 {
  background: hsl(from orchid h calc(s * 1.5) l);
}
(em inglês)

Saturar até uma quantidade específica

O exemplo a seguir .saturate-to-100 não usa o canal s da hsl(), ela especifica um valor de saturação desejado. Neste exemplo, a saturação aumenta para 100%.

.saturate-to-100 {
  background: hsl(from orchid h 100% l);
}

Diminuir a saturação de uma cor

Diminuir a saturação em um valor

O exemplo a seguir .desaturate-by-half usa o s de hsl() para diminuir. a saturação de indigo pela metade.

.desaturate-by-half {
  background: hsl(from indigo h calc(s / 2) l);
}
(link em inglês)

Diminuir a saturação para um valor específico

Em vez de diminuir a saturação por uma quantidade, você pode dessaturar para um valor . O exemplo abaixo, .desaturate-to-25 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);
}

Intensificar uma cor de cromo

Esse efeito é semelhante a saturar uma cor, mas é diferente em alguns de várias formas. Primeiro, é uma mudança de chroma, não de saturation. porque os espaços de cor que podem ser intensificados em High Dynamic Range não usam saturação. Os espaços de cor que apresentam chroma são High Dynamic Range capaz de fazer com que os autores aumentem a vitalidade das cores ainda mais do que a saturação são capazes de realizar.

.increase-chroma {
  background: oklch(from orange l calc(c + .1) h);
}

Ajustar a opacidade de uma cor

Tornar uma variante semitransparente de uma cor é uma das cores mais comuns ajustes feitos em sistemas de design. Confira o exemplo no início deste módulo se não o viu, ele descreve muito bem o espaço do problema.

Ajustar a opacidade em um valor

.decrease-opacity-by-25 {
  background: rgb(from lime r g b / calc(alpha / 2));
}
(link em inglês)

Ajustar a opacidade a 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 cada valor do canal de 1.

.invert-each-rgb-channel {
  background: rgb(from yellow calc(255 - r) calc(255 - g) calc(255 - b));
}
(link em inglês)

Complementar uma cor

Se sua meta não era inverter uma cor, mas complementá-la, use matiz é provavelmente o que você está procurando. Escolha um espaço de cores que ofereça matiz como ângulo, depois use calc() para girar a matiz no valor que você quiser. Encontrar o complemento de uma cor é feito girando em meia volta, neste caso você pode adicionar ou subtrair do canal h por 180 para chegar ao resultado.

.complementary-color {
  background: hsl(from blue calc(h + 180) s l);
}
(em inglês)

Contrastar uma cor

Como um método para atingir taxas de contraste de cores acessíveis, considere L&midast; (Lstar). Isso usa o canal de claridade perceptivamente uniforme (L) da LCH e OKLCH em um calc(). Dependendo da sua segmentação: baixa, média ou alta contraste, L&midast; em torno de ~40, ~50 ou ~60.

(em inglês)

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 inicial é escura (claridade de baixo valor), 60% (0,6) são adicionados para o canal de iluminação. Essa técnica é usada para encontrar uma imagem mesma tonalidade, cor de texto escura em um 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 demonstra L* com um delta de 60% também Como a cor inicial é uma cor clara (claridade de alto valor), 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 cor relativa é muito boa na criação de paletas de cores. É especialmente útil e poderoso devido ao número de espaços de cor disponíveis. O seguinte de exemplo usam OKLCH porque o canal de iluminação é confiável e a tonalidade canal pode ser girado sem efeitos colaterais. O último exemplo demonstra de claridade e ajustes de rotação de matiz para um resultado resultado.

Abra o código-fonte de exemplo e tente mudar --base-color para ver como essas paletas são dinâmicas. É divertido!

Se você gostar do vídeo, posso fornecer informações detalhadas sobre como criar paletas de cores em CSS com o OKLCH no YouTube.

Paletas monocromáticas

Criar uma paleta monocromática é fazer uma paleta toda da mesma tonalidade, mas com variações de claridade e escuridão. A cor do meio é a cor de origem para a paleta, em que duas variantes mais claras e duas mais escuras são colocadas 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 feitas com sintaxe de cores relativa e OKLCH

Open Props, uma biblioteca de variáveis CSS sem custo financeiro, ofertas 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 gera 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 tonalidade em um valor que você goste dos resultados e mude a cor de base, e veja as novas paletas serem 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

Semelhante às cores complementares, paletas de cores triádicas (link em inglês) são rotações de matiz opostas, mas harmoniosas com uma cor de base. Em que a cor complementar está no lado oposto de uma cor, como uma linha reta desenhadas no meio da roda de cores, as paletas triádicas são como uma triângulo de retas, encontrando duas cores igualmente giradas de uma cor de base. Para isso, gire a tonalidade 120deg.

Essa é uma pequena simplificação da teoria das cores, mas é o suficiente para começar com as paletas triádicas mais complexas, se estiver interessado.

: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

Paletas Tetradic são quatro cores divididas uniformemente ao redor da roda de cores, tornando uma paleta sem valor claro dominante. Você também pode pensar nisso, como duas pares de cores complementares. Se usada com sabedoria, ela pode ser muito significativa.

Essa é uma pequena simplificação da teoria das cores, mas é o suficiente para começar com as paletas de tetradic mais complexas, se estiver interessado.

: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 mantêm esse truque na manga. O problema é que a escala de cores monocromática pode ser bastante entediante. A solução é adicionar rotação de matiz maior ou menor para cada nova cor à medida que o brilho é alterado.

O exemplo a seguir diminui a claridade em 10% em cada amostra e também gira o matiz em 10 graus. O resultado, uma paleta de hotpink a índigo que parece se misturam 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 de cabeçalho a seguir usa essa estratégia de rotação de matiz. Cada lista rastreia o índice dele no documento como uma variável com o nome --i. Este índice usada para ajustar o chroma, a luminosidade e a tonalidade. O ajuste é de apenas 5% ou em 5deg, que é muito mais sutil que o exemplo acima com deeppink, então leva uma atento para notar por que esse quadro de liderança pode ter qualquer tonalidade com essa elegância.

Altere o matiz no controle deslizante abaixo do quadro de liderança e veja sintaxe de cor relativa criar belos momentos de cor.

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