Cores na web: Tudo sobre formato de cores no CSS

As cores no CSS definem boa parte da identidade de qualquer página web, porque o arquivo de estilos é a "roupa" que veste o HTML. Em outras palavras, é no CSS que controlamos formatos, fontes, espaçamentos e, principalmente, as cores que o usuário enxerga.

Vemos cores em toda página que acessamos durante o dia. Além disso, conceitos como o círculo cromático orientam quais combinações funcionam melhor em cada situação.

Neste artigo, vamos explorar os diversos formatos de cores disponíveis e entender como usar cada um deles de maneira eficaz. Por fim, vamos ver qual formato faz mais sentido no dia a dia de quem desenvolve para a web.

O mundo das cores no CSS

O CSS oferece uma variedade de formatos de cores, incluindo códigos hexadecimais (HEX), rgb(), hsl(), lch() e outros. No entanto, diante de tantas opções, surge uma pergunta natural: qual delas devemos realmente usar?

Pode parecer que essa decisão não tem grande importância no arquivo de estilos. Contudo, existem diferenças significativas entre as alternativas, e muitas vezes escolhemos o caminho menos adequado.

A especificação oficial que descreve as cores no CSS é o CSS Color Module do W3C, atualmente no nível 4. Ela define tanto as sintaxes quanto os espaços de cores que o navegador entende.

Por isso, vale separar dois conceitos logo no início. O formato é a forma de escrever a cor, enquanto o espaço de cores é o conjunto de cores que aquela escrita consegue alcançar.

Ao longo do texto, também vamos falar do que chamamos de CSS moderno. Assim, você vai perceber como o formato escolhido muda a facilidade de fazer ajustes rápidos.

Cores nomeadas no CSS

Embora esse tipo não seja exatamente um formato de cor, a maioria das pessoas começa a usar cores dessa maneira. Portanto, ele é um bom ponto de partida.

<style>
  body {
    /* cor nomeada: fácil de ler no código */
    color: dodgerblue;
  }
</style>

O CSS reconhece cerca de 148 nomes de cores, como tomato, goldenrod e dodgerblue. Além deles, existem palavras especiais como transparent e currentColor, que herda a cor de texto do próprio elemento.

As cores nomeadas funcionam muito bem como uma espécie de placeholder. Ou seja, quando queremos visualizar rapidamente no código qual cor está sendo aplicada, o nome ajuda bastante.

Apesar de parecer atrativo, em aplicações de produção costumamos preferir valores numéricos em vez de cores nomeadas. Não é uma regra, mas é um padrão adotado, especialmente em aplicações extensas com diversos módulos e funcionalidades.

Afinal, a lista de nomes não cobre os tons exatos de uma identidade visual.

Formato de cor RGB

O RGB é uma das abordagens mais eficazes para trabalhar com cores no CSS. Através de valores numéricos, conseguimos determinar com precisão a cor exata que desejamos.

<style>
  body {
    /* mesma cor do dodgerblue, agora em RGB */
    color: rgb(30 144 255);
  }
</style>

Assim como muitos elementos do CSS, RGB é um acrônimo. Ele representa Red (vermelho), Green (verde) e Blue (azul).

Como funcionam os canais RGB

Entre todos os formatos que vamos explorar, o RGB é o mais abstrato. Isso acontece porque o seu computador ou smartphone exibe cada tom combinando intensidades de luz vermelha, verde e azul, de forma muito parecida com os pixels da tela.

Cada uma dessas luzes está associada ao que chamamos de canal (channel). Cada canal varia de 0 a 255, e podemos atribuir valores diferentes a cada um deles.

Essa flexibilidade nos permite criar mais de 16 milhões de cores distintas. Afinal, 256 possibilidades em cada um dos três canais resultam em 16.777.216 combinações.

Seletor de cores com controles deslizantes para os canais vermelho, verde e azul, usado para definir cores no CSS em RGB
Régua RGB: cada controle ajusta a intensidade de um canal de 0 a 255.

É bastante comum encontrarmos, em vários componentes web, uma régua RGB. Basicamente, ela é um seletor em que escolhemos a cor desejada movendo cada canal.

Essa é, de fato, uma das melhores características do RGB. Como o modelo se baseia em luz, combinamos as intensidades dos três canais para criar praticamente qualquer cor do espaço sRGB.

Transparência com o canal alfa

Além das três cores, o RGB também permite controlar a transparência. Na sintaxe moderna, separada por espaços, o valor de alfa entra depois de uma barra.

.overlay {
  /* preto com 50% de opacidade */
  background-color: rgb(0 0 0 / 50%);
}

.legacy-overlay {
  /* sintaxe antiga, com vírgulas, ainda aceita */
  background-color: rgba(0, 0, 0, 0.5);
}

A sintaxe antiga com vírgulas e a função rgba() continuam funcionando. No entanto, a especificação atual trata rgb() e rgba() como equivalentes, então a forma com barra é a recomendada para código novo.

Códigos hexadecimais

Quando falamos do RGB, destacamos que ele é uma das abordagens mais eficazes. Por outro lado, o HEX, ou código hexadecimal, é sem dúvida o formato mais usado na web.

<style>
  body {
    /* dodgerblue em hexadecimal */
    color: #1E90FF;
  }
</style>

Porém, o HEX também é um dos formatos que mais geram confusão quando tentamos entender seu funcionamento. Então vamos olhar para ele com calma.

Como ler um código HEX

Cada código hexadecimal tem 6 dígitos, organizados em três blocos de 2 dígitos. Essa estrutura existe porque o sistema hexadecimal usa 16 símbolos, de 0 a 9 e de A a F, enquanto o sistema decimal usa apenas 10.

Código hexadecimal dividido em três pares de dígitos, um para cada canal de vermelho, verde e azul
Cada par de dígitos do código HEX representa um canal de cor.

Na prática, o código hexadecimal é muito parecido com o RGB. Em ambos os casos, informamos as intensidades de vermelho, verde e azul.

No sistema decimal, 2 dígitos resultam em 100 possibilidades (10 x 10). Já no hexadecimal temos 256 possibilidades (16 x 16), ou seja, exatamente os valores de 0 a 255 de cada canal RGB.

Por exemplo, em #1E90FF o par 1E vale 30, o par 90 vale 144 e o par FF vale 255. Por isso, ele representa a mesma cor que rgb(30 144 255).

Formas abreviadas e HEX com transparência

O HEX também aceita uma forma abreviada com 3 dígitos. Nesse caso, cada dígito se repete, então #0AF equivale a #00AAFF.

Além disso, existem as versões com 4 e 8 dígitos, em que o último bloco representa o canal alfa. Assim, #00000080 corresponde a um preto com cerca de 50% de opacidade.

Formato HSL nas cores no CSS

Até aqui, todos os formatos seguiram a mesma ideia central: informar valores para os canais de vermelho, verde e azul. No entanto, essa não é a única forma de pensar nas cores no CSS.

Seletor de cores no CSS no formato HSL com controles de matiz, saturação e luminosidade
Editores como Figma e Photoshop oferecem seletores baseados em matiz, saturação e luminosidade.

A imagem acima mostra algo comum em editores como Figma ou Photoshop. Neles, escolhemos uma cor ajustando os valores de Hue (matiz), Saturation (saturação) e Lightness (luminosidade).

Essa abordagem é intuitiva e eficiente. Como podemos observar, ela se divide em três valores distintos.

  • Hue: é o pigmento que queremos usar. Os valores variam de 0 a 360 graus, porque a escala é circular, então 0 e 360 representam o mesmo vermelho.
  • Saturation: indica quanto pigmento existe na cor, de 0% a 100%. Em 0% a cor fica totalmente cinza, enquanto em 100% ela fica o mais vibrante possível.
  • Lightness: indica quão clara ou escura a cor é, também de 0% a 100%. Em 0% a cor é preta e em 100% ela é branco puro.
.button {
  /* aproximadamente o mesmo dodgerblue, agora em HSL */
  background-color: hsl(210 100% 56%);
}

.button:hover {
  /* basta reduzir a luminosidade para escurecer */
  background-color: hsl(210 100% 46%);
}

Essa tende a ser uma forma muito natural de pensar sobre cores. Em vez de controlar diretamente a luz de cada canal, subimos um nível de abstração e chegamos mais perto de como as pessoas descrevem cores.

Repare no exemplo do botão. Para criar o estado de hover, alteramos apenas a luminosidade, sem precisar abrir nenhum seletor de cores.

Formatos modernos de cores no CSS

Todos os formatos que vimos até agora têm uma longa história no mercado. Para ter uma ideia, o HSL chegou à recomendação oficial do W3C em 2011, junto com o módulo CSS Color nível 3.

Recentemente, porém, novos formatos de cores no CSS passaram a funcionar em todos os navegadores modernos. Segundo o web.dev, color(), lab(), lch(), oklab() e oklch() estão disponíveis desde o Chrome 111, o Edge 111, o Firefox 113 e o Safari 15.

Com isso, podemos incorporar esses formatos no dia a dia sem grandes preocupações de compatibilidade. Ainda assim, vale entender o que cada um resolve antes de adotá-lo.

Display P3 e os espaços de cores

Tudo o que abordamos até agora está ligado às sintaxes disponíveis para escrever cores no CSS. Todos esses formatos, RGB, HEX e HSL, trabalham dentro do espaço de cores padrão, chamado sRGB.

Um espaço de cores é uma seleção de cores disponíveis, ou seja, a paleta da qual podemos escolher. Embora o sRGB tenha milhões de cores, ele ainda está longe de capturar tudo o que o olho humano percebe.

Dois quadrados vermelhos lado a lado, o da esquerda em sRGB e o da direita em Display P3, mais intenso
O vermelho em Display P3, à direita, vai além do vermelho máximo do sRGB.

O quadrado da esquerda usa rgb(255 0 0), que é o vermelho mais intenso que conseguimos no sRGB. Já o quadrado da direita usa o espaço Display P3 e é ainda mais vermelho.

Uma pequena observação: se os dois quadrados parecem idênticos, talvez o seu monitor não suporte a gama ampla do Display P3. Nesse caso, vale conferir em um smartphone recente, como um iPhone, em que a diferença costuma aparecer.

O Display P3 oferece uma gama mais ampla de cores e brilho. De acordo com a documentação do Chrome, ele contém cerca de 50% mais cores que o sRGB.

Diagrama de cores no CSS comparando a área do espaço sRGB com a área maior do Display P3
O Display P3 cobre uma área maior do espectro visível que o sRGB.

No CSS, o espaço de cores está vinculado ao formato. Portanto, se usamos rgb(), códigos hexadecimais ou hsl(), só conseguimos especificar cores do sRGB.

Para usar o espaço P3, precisamos de outro formato. Veja a sintaxe com a função color():

<style>
  body {
    /* vermelho máximo do espaço Display P3 */
    background: color(display-p3 1 0 0);
  }
</style>

A função color() recebe primeiro o espaço de cores e, em seguida, os valores de vermelho, verde e azul. Em vez de ir de 0 a 255, cada valor usa decimais de 0 a 1.

Quando a tela não suporta o P3, o navegador ajusta a cor para o valor mais próximo dentro da gama disponível. Mesmo assim, é uma boa prática declarar antes uma cor em sRGB como alternativa.

.highlight {
  /* fallback em sRGB para navegadores e telas antigas */
  background: rgb(255 0 0);
  /* versão de gama ampla quando houver suporte */
  background: color(display-p3 1 0 0);
}

LCH e OKLCH no CSS

Para entender por que o LCH existe, observe a imagem abaixo. Usamos o modelo HSL para criar as duas cores e, em ambas, a luminosidade está configurada em 50%.

Duas cores em HSL com luminosidade de 50% que aparentam ter claridades diferentes
Mesmo com a mesma luminosidade em HSL, as cores não parecem igualmente claras.

Entretanto, mesmo com os dois valores em 50%, as cores não parecem igualmente claras. Isso acontece porque o HSL segue princípios matemáticos e físicos, sem levar totalmente em conta a percepção humana.

O formato LCH foi projetado para ser uniforme aos olhos humanos. Dessa forma, duas cores com a mesma luminosidade devem parecer igualmente claras.

Duas cores no CSS definidas em LCH com a mesma luminosidade e claridade percebida equivalente
No LCH, a mesma luminosidade resulta em claridade percebida parecida.

LCH significa Lightness, Chroma e Hue. Chroma é praticamente um sinônimo de saturação, então o conceito lembra bastante o HSL.

Mesmo assim, existem duas diferenças importantes:

  • O formato é centrado na percepção humana, garantindo que cores com a mesma luminosidade aparentem a mesma claridade.
  • Ele não pertence a nenhum espaço de cores fixo, como o sRGB ou o P3.

No HSL, a saturação vai de 0% a 100%, porque sabemos que estamos dentro do sRGB, uma paleta finita. Em outras palavras, conhecemos o limite máximo.

Já o LCH não tem um limite superior definido para o Chroma. Na prática, valores próximos de 230 já ultrapassam qualquer tela atual, e o navegador ajusta a cor para a gama que o monitor consegue exibir.

<style>
  body {
    /* luminosidade 50%, chroma alto e matiz 20 graus */
    background: lch(50% 500 20);
  }
</style>

Essa independência tem uma vantagem interessante. À medida que os monitores alcançam gamas mais amplas, o LCH consegue referenciar essas cores apenas aumentando o Chroma.

Além do LCH, os navegadores também suportam o OKLCH, uma variação mais recente. Ele corrige distorções do LCH em tons de azul e roxo, e por isso o guia do Chrome o recomenda para sistemas de cores e interfaces.

:root {
  /* paleta com a mesma luminosidade percebida */
  --color-primary: oklch(60% 0.15 250);
  --color-danger: oklch(60% 0.15 25);
}

Como escolher o formato de cores no CSS

Depois de analisar tantas opções, chega a grande pergunta: qual formato de cores no CSS devemos escolher? A resposta depende do contexto, mas alguns critérios ajudam.

Muitas pessoas gostam de códigos hexadecimais. Eles são concisos e fáceis de copiar entre o software de design e o código, porém esses benefícios cobram um preço.

Mesmo para quem está acostumado com HEX, ler o valor continua difícil. Por exemplo, qual cor é #0F52B7 ou #F32AB9?

Por isso, o HSL costuma ser uma escolha muito confortável. Ele está alinhado com a forma como pensamos sobre cores, e com um pouco de prática você passa a imaginar a cor só de olhar o valor.

Isso também significa ajustar valores em tempo real com facilidade. Se a cor precisa ficar mais escura, diminuímos a luminosidade, e se precisa ficar mais intensa, aumentamos a saturação.

O HSL fica ainda mais poderoso quando o combinamos com recursos modernos, como variáveis CSS. Assim, uma única variável de matiz pode gerar toda uma família de tons.

:root {
  /* matiz da marca reaproveitado em toda a paleta */
  --brand-hue: 210;
  --color-brand: hsl(var(--brand-hue) 100% 56%);
  --color-brand-dark: hsl(var(--brand-hue) 100% 40%);
  --color-brand-light: hsl(var(--brand-hue) 100% 90%);
}

Resumo dos formatos de cores no CSS

Escolher o formato adequado impacta a estética, a legibilidade e a manutenção do código.

Os códigos hexadecimais são práticos, mas difíceis de interpretar, enquanto o HSL vira uma linguagem visual com a prática. O RGB oferece precisão matemática, e as cores nomeadas servem como ponto de partida.

Já o Display P3 amplia as possibilidades, mas telas sem gama ampla exibem as cores de forma diferente.

Por fim, LCH e OKLCH levam as cores no CSS em direção à percepção humana.

Em resumo, projetos que exigem precisão matemática podem se beneficiar do RGB. Já quem valoriza comunicação clara no código tende a encontrar no HSL ou no OKLCH uma escolha mais adequada.

Curso gratuito de fundamentos do HTML e do CSS

Banner de divulgação do curso gratuito Fundamentos do HTML e do CSS do balta.io
O curso gratuito do balta.io cobre a base de HTML e CSS para quem está começando.

Por onde começar a estudar HTML? Uma ótima maneira é dar uma chance ao curso gratuito, que apresenta os conceitos fundamentais dessas duas tecnologias presentes em quase todas as aplicações do mercado.

O curso se destina a qualquer pessoa interessada em criar páginas web, desde iniciantes completos até desenvolvedores que querem aprimorar as habilidades. Não é necessário ter experiência prévia em programação, apenas vontade de aprender.

Se você está dando os primeiros passos, também vale ler o que você precisa saber antes de aprender HTML. Em seguida, o guia completo de formulários no HTML ajuda a aplicar esses estilos em telas reais.

Confira o curso gratuito

Conclusão sobre cores no CSS

Lidar com cores no CSS vai muito além da estética de uma página. Na verdade, é um campo cheio de lógica e significado, capaz de transformar completamente a experiência de uma aplicação.

Cada formato tem vantagens e aplicações particulares. Por isso, conhecer HEX, RGB, HSL, Display P3, LCH e OKLCH permite escolher conscientemente, em vez de repetir o hábito de sempre.

E você, de qual maneira prefere trabalhar com cores no CSS? Bons códigos e até a próxima.

FAQ

Qual é o formato de cor mais usado no CSS?

O código hexadecimal (HEX) é o mais usado na web, principalmente porque é curto e fácil de copiar de ferramentas de design. Mesmo assim, ele é mais difícil de interpretar do que o HSL.

HEX e RGB representam as mesmas cores?

Sim. Ambos descrevem intensidades de vermelho, verde e azul no espaço sRGB, então #1E90FF e rgb(30 144 255) são a mesma cor.

Como adicionar transparência a uma cor no CSS?

Use o canal alfa depois de uma barra, como em rgb(0 0 0 / 50%) ou hsl(210 100% 56% / 0.5). No HEX, use a versão de 8 dígitos, como #00000080.

O que acontece se a tela não suportar Display P3?

O navegador ajusta a cor para o valor mais próximo que a tela consegue exibir. Por isso, declarar antes uma cor em sRGB como fallback é uma boa prática.

Qual a diferença entre LCH e OKLCH?

Os dois descrevem cores por luminosidade, chroma e matiz de forma perceptualmente uniforme. O OKLCH corrige distorções do LCH em tons de azul e roxo.

Os navegadores já suportam lch(), oklch() e color()?

Sim. Chrome e Edge 111, Firefox 113 e Safari 15 em diante suportam essas funções.

Glossário

Termo Significado
HEX Notação hexadecimal de cores, com pares de dígitos para vermelho, verde e azul
RGB Modelo de cor que combina intensidades de luz vermelha, verde e azul
HSL Modelo de cor baseado em matiz, saturação e luminosidade
Canal alfa Valor que define a opacidade de uma cor
sRGB Espaço de cores padrão da web, usado por HEX, RGB e HSL
Display P3 Espaço de cores com gama mais ampla que o sRGB
LCH Formato de cor perceptualmente uniforme baseado em luminosidade, chroma e matiz
OKLCH Variação do LCH com correções em tons de azul e roxo
Chroma Intensidade da cor, conceito próximo de saturação
Gamut Conjunto de cores que uma tela ou espaço de cores consegue representar

Fontes