Uma visão geral básica de como estabelecer um esquema de cores dinâmico e configurável
Nesta postagem, quero compartilhar ideias sobre maneiras de gerenciar vários esquemas de cores no CSS. Teste a demonstração.
Se você preferir o vídeo, aqui está uma versão do YouTube desta postagem:
Visão geral
Vamos criar um sistema de cores acessível com propriedades personalizadas e calc()
para
crie uma página da Web que se adapte às preferências do usuário, mantendo a criação
experiência mínima. Começamos com uma cor de marca de base e criamos um sistema de
duas cores de texto, quatro cores de superfície e uma sombra correspondente.
Este guia começa com a definição de todas as cores para cada esquema de cores frente. Só até o final eles são usados para alterar a página.
A marca
Muitas vezes, a cor de uma marca já foi estabelecida e é fornecida como
hex ou
rgb. Este desafio de GUI
tem uma cor de marca base de #0af
. Primeiro, para esse sistema de cores, o valor hexadecimal
necessidades convertidas em
hsl.
* {
--brand: #0af;
--brand: hsl(200 100% 50%);
}
Para permitir um conceito de escurecer ou clarear a cor da marca, por exemplo, 20%, os 3 canais do valor de cor de hsl precisam ser extraídos para suas próprias , da seguinte forma:
* {
--brand-hue: 200;
--brand-saturation: 100%;
--brand-lightness: 50%;
}
O CSS pode fazer cálculos matemáticos nessas propriedades de cor, por exemplo, calc(var(--brand-lightness) -
20%)
para diminuir o valor de brilho em 20%. Isso é fundamental para criar
esquema de cores, pois o CSS pode manter todas as cores na mesma família de matiz ajustando o
valores de saturação e luminosidade de hsl.
Tema claro
Cada variante de cor será marcada com o esquema correspondente.
é anexado com -light
.
Marca
Começando com a cor da marca, ele é recriado ao combinar --brand-hue
e --brand-saturation
.
e --brand-lightness
dentro do parêntese da função ()
de hsl,
sem cálculos:
* {
--brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
}
Cores do texto
Em seguida, os fundamentos de um esquema de cores precisam de cores de texto. Em um tema claro, o texto deve ser muito escuro. Observe como o brilho das seguintes cores é baixo, bem abaixo de 50%.
* {
--text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
--text2-light: hsl(var(--brand-hue) 30% 30%);
}
--text1-light
, já que é muito escuro a 10% de iluminação, mantém a grossa 100%
para que a cor da marca ainda apareça no azul-marinho escuro.
--text2-light
, ela não é tão escura quanto a primeira cor, o que é bom, mas é
uma cor secundária e também muito menos saturada.
Cores da superfície
As cores da superfície são os planos de fundo, bordas e outras superfícies decorativas que o texto fica sobre ou dentro dele. Em um tema claro, essas são as cores claras, em oposição às cores de texto, que eram escuras. Para criar cores claras com hsl, vamos usar valores percentuais mais altos no terceiro valor de iluminação. Também diminuiremos a saturação, para que os cinzas-claro não pareçam muito coloridos.
* {
--surface1-light: hsl(var(--brand-hue) 25% 90%);
--surface2-light: hsl(var(--brand-hue) 20% 99%);
--surface3-light: hsl(var(--brand-hue) 20% 92%);
--surface4-light: hsl(var(--brand-hue) 20% 85%);
}
Quatro cores de superfície foram criadas, já que cores decorativas tendem a precisar de mais
variantes, para momentos interativos como :focus
ou :hover
, ou para criar a
a aparência das camadas de papel. Nesses cenários, é bom fazer a transição
--surface2-light
ao passar o cursor para --surface3-light
, ou seja, passar o cursor resulta em uma
aumento do contraste (99% de claridade para 92% de claridade, tornando-o mais escuro).
Sombras
Sombras dentro de um esquema de cores estão acima e além, mas adicionam uma natureza realista ao o efeito e ajudá-lo a se destacar de sombras pretas irrealistas. Afazeres isso, a cor da sombra usará a propriedade personalizada matiz, será ligeiramente saturada de tonalidade, mas ainda muito escura. Basicamente, a construção de uma uma sombra levemente azul.
* {
--surface-shadow-light: var(--brand-hue) 10% 20%;
--shadow-strength-light: .02;
}
--surface-shadow-light
não está encapsulado em uma função hsl. Isso ocorre porque o
O valor --shadow-strength
será combinado para criar alguma opacidade, e o CSS precisa
as peças para realizar cálculos. Vá direto para a sombra radical
para saber mais.
Cores claras em um só lugar
Não é preciso procurar para descobrir como as cores claras são feitas, elas são tudo em um só lugar no CSS.
* {
--brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
--text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
--text2-light: hsl(var(--brand-hue) 30% 30%);
--surface1-light: hsl(var(--brand-hue) 25% 90%);
--surface2-light: hsl(var(--brand-hue) 20% 99%);
--surface3-light: hsl(var(--brand-hue) 20% 92%);
--surface4-light: hsl(var(--brand-hue) 20% 85%);
--surface-shadow-light: var(--brand-hue) 10% calc(var(--brand-lightness) / 5);
--shadow-strength-light: .02;
}
Tema escuro
A maioria das marcas não começa com um tema escuro, ele é uma variante do tema principal, geralmente um tema mais claro. Os usuários, por outro lado, geralmente escolhem um tema escuro para contextos diferentes, como a noite. Esses fatores me fizeram manter duas coisas em mente com os temas escuros:
- Os usuários geralmente ficam no escuro ao usar esse tema, então teste no escurecer.
- As cores devem diminuir a saturação para não vibrar na tela por serem excessivamente intensa.
Marca
O tema claro usou os 3 valores dos canais de cor HDR da marca sem alteração, o tema escuro não. A saturação é reduzida pela metade e o brilho, em cerca de 50%.
* {
--brand-dark: hsl(
var(--brand-hue)
calc(var(--brand-saturation) / 2)
calc(var(--brand-lightness) / 1.5)
);
}
Cores do texto
Em um tema escuro, as cores do texto precisam ser claras. As cores a seguir têm alto valores de claridade, colocando-os mais próximos do branco.
* {
--text1-dark: hsl(var(--brand-hue) 15% 85%);
--text2-dark: hsl(var(--brand-hue) 5% 65%);
}
Cores da superfície
Em um tema escuro, as cores da superfície precisam ser escuras. As cores a seguir têm pouca luminosidade e saturação, sendo que a 1a superfície é a mais escura a 10%.
* {
--surface1-dark: hsl(var(--brand-hue) 10% 10%);
--surface2-dark: hsl(var(--brand-hue) 10% 15%);
--surface3-dark: hsl(var(--brand-hue) 5% 20%);
--surface4-dark: hsl(var(--brand-hue) 5% 25%);
}
Sombras
Em um tema escuro, as sombras podem ser muito difíceis de enxergar. Faz sentido, já que é difícil
escurecer algo que já é bastante escuro. É aqui que
O --shadow-strength-dark
é muito útil porque permite escurecer o
as sombras, mudando uma variável.
* {
--surface-shadow-dark: var(--brand-hue) 50% 3%;
--shadow-strength-dark: .8;
}
Observe também o nível de saturação dessa sombra. Consegue notar a cor quando você está olhando para a interface? Tente remover a saturação do DevTools, qual você prefere?!
Cores escuras juntas
* {
--brand-dark: hsl(var(--brand-hue) calc(var(--brand-saturation) / 2) calc(var(--brand-lightness) / 1.5));
--text1-dark: hsl(var(--brand-hue) 15% 85%);
--text2-dark: hsl(var(--brand-hue) 5% 65%);
--surface1-dark: hsl(var(--brand-hue) 10% 10%);
--surface2-dark: hsl(var(--brand-hue) 10% 15%);
--surface3-dark: hsl(var(--brand-hue) 5% 20%);
--surface4-dark: hsl(var(--brand-hue) 5% 25%);
--surface-shadow-dark: var(--brand-hue) 50% 3%;
--shadow-strength-dark: .8;
}
Escurecer tema
Esse esquema de cores trata da orquestração de luminosidade e saturação. deve haver saturação suficiente para ainda ter uma matiz visível, mas também apenas passam as pontuações de contraste, já que é devem ser escuros e com baixo contraste.
Marca
* {
--brand-dim: hsl(
var(--brand-hue)
calc(var(--brand-saturation) / 1.25)
calc(var(--brand-lightness) / 1.25)
);
}
Cores do texto
* {
--text1-dim: hsl(var(--brand-hue) 15% 75%);
--text2-dim: hsl(var(--brand-hue) 10% 61%);
}
Cores da superfície
* {
--surface1-dim: hsl(var(--brand-hue) 10% 20%);
--surface2-dim: hsl(var(--brand-hue) 10% 25%);
--surface3-dim: hsl(var(--brand-hue) 5% 30%);
--surface4-dim: hsl(var(--brand-hue) 5% 35%);
}
Sombras
* {
--surface-shadow-dim: var(--brand-hue) 30% 13%;
--shadow-strength-dim: .2;
}
Escurecer todas as cores juntas
* {
--brand-dim: hsl(var(--brand-hue) calc(var(--brand-saturation) / 1.25) calc(var(--brand-lightness) / 1.25));
--text1-dim: hsl(var(--brand-hue) 15% 75%);
--text2-dim: hsl(var(--brand-hue) 10% 61%);
--surface1-dim: hsl(var(--brand-hue) 10% 20%);
--surface2-dim: hsl(var(--brand-hue) 10% 25%);
--surface3-dim: hsl(var(--brand-hue) 5% 30%);
--surface4-dim: hsl(var(--brand-hue) 5% 35%);
--surface-shadow-dim: var(--brand-hue) 30% 13%;
--shadow-strength-dim: .2;
}
Cores acessíveis
Observe como o mínimo de brilho no conjunto de cores de texto escuro é de 65%, e o maior luminosidade em superfícies escuras é de 25%. Isso é 40% do brilho espaço entre eles. No tema claro, há 55% de espaço o tema claro. Manter as diferenças de claridade entre as cores do texto e da superfície entre 40 e 50% pode ajudar a manter altas taxas de contraste de cores, um elemento sutil para ajustar caso as pontuações sejam ruins.
Eu chamo de "bump bump til ya pass", que é a interação de bater no lightness até que uma ferramenta mostre que passei.
Todos os temas criados neste desafio são aprovados nas pontuações de contraste. O esquema de cores mais escuro tem o menor contraste entre elas, mas ainda atende aos requisitos mínimos. Para ajudar os outros membros da equipe a usar cores contrastantes, é uma boa ideia criar um nome de classe que combine uma cor de superfície com uma cor de texto acessível.
.surface1 {
background-color: var(--surface1);
color: var(--text2);
}
.surface2 {
background-color: var(--surface2);
color: var(--text2);
}
.surface3 {
background-color: var(--surface3);
color: var(--text1);
}
.surface4 {
background-color: var(--surface4);
color: var(--text1);
}
Sombra radical
Os temas usam uma classe de utilitário chamada .rad-shadow
. Esta sombra foi gerada
ferramenta Smooth Shadow, que agradeço muito
muito. Peguei o snippet gerado e o personalizei com minhas próprias cores e
cálculos de opacidade. A razão disso foi criar uma sombra que eu pudesse ajustar
dentro de cada esquema de cores.
Para isso, criei duas variáveis para cada esquema de cores ajustar, uma cor da sombra e intensidade da sombra. A cor serve para saturação e escuridão ajustes, enquanto a intensidade serve como uma forma fácil de aumentar a sombra intensidade quando se tem um esquema de cores escuras. O resultado final ficou assim.
:root {
--surface-shadow-light: var(--brand-hue) 10% 20%;
--shadow-strength-light: .02;
}
.rad-shadow {
box-shadow:
0 2.8px 2.2px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
0 6.7px 5.3px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .01)),
0 12.5px 10px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
0 22.3px 17.9px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
0 41.8px 33.4px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
0 100px 80px hsl(var(--surface-shadow) / var(--shadow-strength))
;
}
Se eu fosse além usando sombras no meu esquema de cores, eu faria a sombra uma constante de token de design, já que a direção da luz precisa ser a mesma entre todas as sombras do design.
Uso dos esquemas de cores
Com a predefinição das cores concluída, é hora de transformá-las propriedades independentes de esquema. O que quero dizer é, como um CSS nesse projeto de esquema de cores, raramente será necessário acessar uma o valor do esquema de cores específico. Quero facilitar a manutenção do tema.
Para isso, o uso do esquema de cores deve ser feito exclusivamente por meio de
as propriedades personalizadas genéricas, que serão definidas em breve. Assim,
As pessoas que usam as variáveis de design nunca precisam se preocupar com qual esquema de cores é
definido no momento, basta usar as cores de superfície e texto. Em vez de
color: var(--text1-light)
usam color: var(--text1)
. Tudo sobre adaptação e mudança
de cores é feito em um nível muito mais alto no CSS.
Os estilos de conexão do tema claro são abordados no bloco de código a seguir.
conecta uma propriedade personalizada genérica com a cor específica do tema claro. Agora todos
os usos de var(--brand)
usarão a cor clara da marca.
Tema claro (automático)
:root {
color-scheme: light;
--brand: var(--brand-light);
--text1: var(--text1-light);
--text2: var(--text2-light);
--surface1: var(--surface1-light);
--surface2: var(--surface2-light);
--surface3: var(--surface3-light);
--surface4: var(--surface4-light);
--surface-shadow: var(--surface-shadow-light);
--shadow-strength: var(--shadow-strength-light);
}
O site está usando o tema claro. Este é um momento de sucesso muito divertido! Vamos ter mais alguns desses momentos à medida que usamos nossas cores predefinidas em outros contextos de esquema de cores.
Tema escuro (automático)
@media (prefers-color-scheme: dark) {
:root {
color-scheme: dark;
--brand: var(--brand-dark);
--text1: var(--text1-dark);
--text2: var(--text2-dark);
--surface1: var(--surface1-dark);
--surface2: var(--surface2-dark);
--surface3: var(--surface3-dark);
--surface4: var(--surface4-dark);
--surface-shadow: var(--surface-shadow-dark);
--shadow-strength: var(--shadow-strength-dark);
}
}
Tema claro
[color-scheme="light"] {
color-scheme: light;
--brand: var(--brand-light);
--text1: var(--text1-light);
--text2: var(--text2-light);
--surface1: var(--surface1-light);
--surface2: var(--surface2-light);
--surface3: var(--surface3-light);
--surface4: var(--surface4-light);
--surface-shadow: var(--surface-shadow-light);
--shadow-strength: var(--shadow-strength-light);
}
Tema escuro
[color-scheme="dark"] {
color-scheme: dark;
--brand: var(--brand-dark);
--text1: var(--text1-dark);
--text2: var(--text2-dark);
--surface1: var(--surface1-dark);
--surface2: var(--surface2-dark);
--surface3: var(--surface3-dark);
--surface4: var(--surface4-dark);
--surface-shadow: var(--surface-shadow-dark);
--shadow-strength: var(--shadow-strength-dark);
}
Escurecer tema
[color-scheme="dim"] {
color-scheme: dark;
--brand: var(--brand-dim);
--text1: var(--text1-dim);
--text2: var(--text2-dim);
--surface1: var(--surface1-dim);
--surface2: var(--surface2-dim);
--surface3: var(--surface3-dim);
--surface4: var(--surface4-dim);
--surface-shadow: var(--surface-shadow-dim);
--shadow-strength: var(--shadow-strength-dim);
}
Neste ponto, os autores estão livres para usar os genéricos de esquema de cores fornecidos como necessário e nunca mais deve se preocupar com temas.
Conclusão
Agora que você sabe como eu fiz isso, como faria?! 🙂
Vamos diversificar nossas abordagens e aprender todas as maneiras de criar na Web. Crie um Codepen ou hospede sua própria demonstração, envie um tweet para mim e eu a adicionarei ao seção "Remixes da comunidade" abaixo.
Origem
Remixes da comunidade
- @chris-kruining adicionou um controle deslizante de matiz
cores de status e modos de contraste para no-preference
, more
e less
:
demonstração.