11 pontos por GN⁺ 2025-08-26 | 1 comentários | Compartilhar no WhatsApp
  • OKLCH é um modelo de cor moderno ajustado à percepção visual humana, com a característica de que as mudanças de brilho, saturação e matiz entre cores são percebidas de forma uniforme, sendo um modelo de cor perceptualmente uniforme
  • Sua estrutura é composta por Lightness (luminosidade), Chroma (croma/saturação), Hue (matiz), e em comparação com modelos anteriores permite montar paletas de cores mais consistentes
  • Mantendo o mesmo brilho e croma e alterando apenas o Hue, é possível criar uma paleta uniforme, o que é vantajoso para design de UI
  • Em comparação com sRGB/HSL, oferece mudanças de contraste mais previsíveis e gradientes mais uniformes, embora em alguns casos possa gerar cores não intencionais
  • Em displays modernos como o Display-P3, permite uma representação de cores mais ampla e, nos navegadores recentes, é suportado via CSS Color 4, além de oferecer fallback para sRGB, consolidando-se gradualmente como padrão da web

Introdução ao modelo de cor OKLCH

  • OKLCH é um modelo de cor moderno desenvolvido com foco em uniformidade perceptual (perceptually uniform)
  • Esse modelo funciona de forma mais próxima de como as pessoas realmente percebem as cores, tornando muito mais prático trabalhar com cores em design digital e desenvolvimento frontend

Conceitos básicos de modelos de cor

  • Um modelo de cor é um sistema que define e representa cores matematicamente
  • Exemplos de modelos comumente usados: RGB, HSL, LCH, OKLCH, LAB, XYZ
  • Cada modelo determina a facilidade de representar e manipular cores

Exemplos de notação de cores

  • oklch(0.55 0.18 260)
  • hsl(220 100% 50%)
  • rgb(0, 128, 255)
  • lch(60% 60 260)
  • lab(50 -10 -50)
  • color(xyz 0.18 0.19 0.6)
  • #1E90FF

Gamut (faixa do espaço de cor)

  • Gamut significa a faixa total de cores que um determinado modelo de cor consegue representar
  • Gamuts representativos: sRGB (padrão da web), Display-P3 (suportado por dispositivos modernos)
  • Além da faixa de gamut, um espaço de cor também possui várias outras propriedades, como white point e transfer function

Estrutura do OKLCH

Tanto o OKLCH quanto o LCH são compostos por três valores: Lightness, Chroma, Hue
O OKLCH é baseado no espaço de cor OKLab

  • Lightness (claridade/luminosidade): expresso de 0 a 1 ou de 0% a 100%, garantindo mudanças uniformes de brilho
  • Chroma (croma/saturação): intensidade da cor, semelhante à Saturation (saturação) do HSL
  • Hue (matiz): representa a cor em um ângulo de 0 a 360 graus

Vantagens e usos do OKLCH

  • Brilho consistente

    • No OKLCH, ao definir cores com o mesmo brilho e croma e apenas um hue diferente, todas as cores tendem a ser percebidas com brilho semelhante
    • Em sRGB ou HSL tradicionais, brilho e saturação podem parecer inconsistentes dependendo da cor
    • Por isso, o OKLCH facilita a criação de paletas de cores perceptualmente uniformes
  • Etapas previsíveis de luminosidade da cor

    • No OKLCH, ao alterar o brilho, é possível gerar vários níveis de cor sem mudar o hue (matiz) ou o chroma (croma)
    • Em HSL e similares, ao mudar o brilho pode ocorrer um efeito de deriva de matiz
    • Com OKLCH, é possível criar etapas consistentes de luminosidade ajustando apenas o brilho
  • Forma de lidar com gradientes (Gradients)

    • No sRGB, a interpolação ocorre entre os valores de vermelho, verde e azul, então o ponto intermediário pode ficar opaco ou apresentar grande variação de brilho
    • O OKLCH faz a interpolação ao longo dos eixos Lightness, Chroma e Hue, permitindo gradientes mais naturais
    • Porém, como o Hue tem estrutura circular, podem surgir variações inesperadas de cor
    • Para evitar isso, é possível fazer interpolação linear no OKLab, obtendo resultados mais previsíveis

Suporte a espaços de cor

  • O sRGB não consegue cobrir parte do amplo espaço de cor exibido por displays modernos
  • Com OKLCH, é possível representar cores mais vivas em dispositivos que suportam gamas amplas, como Display-P3
  • Em dispositivos que suportam apenas sRGB, as cores são mapeadas para as mais semelhantes possíveis

Valor máximo de Chroma (saturação)

  • O OKLCH permite definir matematicamente até mesmo cores fora da faixa que uma tela real consegue exibir
  • Por exemplo, um valor de chroma muito alto como oklch(0.7 0.4 40) não pode ser exibido na prática e será recortado para uma cor próxima
  • É importante entender o conceito de chroma máximo e ajustar os valores adequadamente conforme o matiz, o brilho e o espaço de cor escolhido (sRGB, Display-P3)

Suporte dos navegadores e fallback

  • As cores OKLCH foram introduzidas no CSS Color Module Level 4 e já são suportadas pela maioria dos navegadores modernos
  • Em navegadores antigos, o suporte pode não existir, então é possível definir valores de fallback usando a diretiva CSS @supports
    @layer base {  
      :root {  
        /* sRGB hex */  
        --color-gray-100: #fcfcfc;  
        --color-gray-200: #fafafa;  
        --color-gray-300: #f4f4f4;  
    
        @supports (color: oklch(0 0 0)) {  
          /* OKLCH */  
          --color-gray-100: oklch(0.991 0 0);  
          --color-gray-200: oklch(0.982 0 0);  
          --color-gray-300: oklch(0.955 0 0);  
        }  
      }  
    }  
    
  • Em navegadores compatíveis, aplica-se OKLCH; nos não compatíveis, aplicam-se cores sRGB (hex)

Ferramenta oklch.fyi

  • oklch.fyi é uma ferramenta web que oferece recursos relacionados a OKLCH, como geração de paletas de cores e conversão de variáveis CSS
  • Ela ajuda a usar cores OKLCH com mais facilidade em sistemas de design, desenvolvimento de temas e outros contextos

1 comentários

 
GN⁺ 2025-08-26
Comentários no Hacker News
  • Fiquei desconfiado dessa funcionalidade de “Better Gradients”. OKLCH é um espaço polar, e nele o hue funciona como um ângulo. Ao interpolar cores entre dois pontos diferentes, você acaba se movendo pela borda do círculo. Por exemplo, se usar linear-gradient(in oklch, #f0f, #0f0), a transição de verde para roxo sai visivelmente da faixa de cores. Se der a volta pelo outro lado do círculo, como em linear-gradient(in oklch longer hue, #f0f, #0f0), você passa por turquesa ou aqua. Esses caminhos mostram como esse espaço de cor perceptual lida de forma bem incômoda com os limites do sRGB ou da faixa de cores perceptível ao ser humano, ou seja, o gamut. Na prática, basta uma diferença mínima nos valores para a cor sair da faixa. Existem vários algoritmos para resolver isso, mas a uniformidade perceptual acaba sendo sacrificada. Por exemplo, o vermelho no gradiente fica estranhamente escuro. Se você quer gradientes melhores e a uniformidade perceptual é importante, na verdade a interpolação em Oklab deveria ser o padrão. O Oklab interpola em linha reta atravessando o círculo e, se necessário, até passa pelo cinza (linear-gradient(in oklab, #f0f, #0f0)). Esse método também elimina aquele escurecimento comum da interpolação em sRGB e cria um gradiente natural de magenta até lime. Aliás, o Tailwind v4 usou Oklch em vez de sRGB durante o beta, mas na versão final escolheu Oklab como padrão mais seguro

    • Acho que a forma como os navegadores interpolam cores em sRGB é praticamente um bug. sRGB é uma codificação em escala logarítmica, então, pela especificação original, a interpolação não deveria ser feita diretamente em sRGB, mas sim após converter para RGB linear

    • Como este texto foi corrigido, meu comentário pode ser ignorado. Ainda assim, concordo que a interpolação em Oklab deveria ser o padrão. O texto também diz, sobre “gradientes melhores”, que o hue circular do OKLCH pode produzir trajetórias inesperadas. Para evitar isso, muitas ferramentas usam OKLAB, e o Oklab dá resultados consistentes em trajetórias retas

    • Na verdade, o CIE LAB já cumpre esse mesmo papel e já existe como padrão (Wikipedia do CIE LAB)
      Material de revisão do W3C

    • Obrigado pela explicação extremamente útil. Eu sou a pessoa que escreveu este texto. Vou revisá-lo para explicar isso com mais clareza

    • Fazer um gradiente com duas cores em lados opostos do espectro é um caso meio extremo. Também não existe uma resposta certa de como isso deveria parecer e, na prática, acho raro um design realmente precisar desse tipo de gradiente. Normalmente, ao usar gradientes em design, você acaba escolhendo manualmente a cor intermediária

  • Sobre OKLCH, o oklch.com me ajudou a criar intuição. Só é preciso lembrar que o valor de hue é diferente do hue do HSL, e que o chroma máximo varia conforme o hue e a lightness. Isso não é bug, mas reflexo das características da visão humana e dos displays. Ao contrário do OKLCH, o HSL sempre tem o mesmo máximo, mas o significado das cores não é consistente. O legal do OKLCH no CSS é que ele pode ser manipulado em forma de fórmula. Por exemplo, dá para escrever oklch(from var(--accent) calc(l + .1) c h). Mas, para usar bem essas fórmulas na prática, é preciso conhecer teoria das cores ou testar bastante. Por exemplo, eu achava que para sombras bastava mudar a lightness, mas na prática o hue também precisa mudar. Isso não quer dizer que gradientes em OKLCH sejam sempre os melhores. Quando se usam hues parecidos, as cores realmente parecem mais uniformes, mas se você também quer considerar como a luz se mistura fisicamente de verdade, precisa do espaço de cor XYZ. Sobre isso, vale consultar a documentação do MDN sobre color-mix. Aliás, o “ok” vem literalmente da palavra OK mesmo. O nome surgiu porque o LCH anterior tinha problemas, ou seja, não estava OK

    • Você disse que é legal poder usar fórmulas no OKLCH do CSS, mas na verdade manipulação relativa de cor pode ser usada em todos os espaços de cor do CSS. Por exemplo, dá para usar background-color: rgb(from var(--base-color) calc(r - 76.5) g calc(b + 76.5));

    • Graças ao OKLCH e às cores relativas, consegui reduzir bastante a quantidade de cores hardcoded na stylesheet
      Exemplo de variáveis CSS

  • Algumas críticas já foram mencionadas, mas ainda acho que é um texto bem bom como introdução ao OKLCH e à forma de aplicá-lo em CSS. Como pergunta paralela, fiquei curioso com a tendência recente de não colocar datas em posts de blog. Especialmente porque a frase “OKLCH é um novo modelo de cor” vai envelhecer rápido no futuro. No site principal só aparece “agosto de 2025”, então parece até que a ausência da data é intencional
    Site relacionado

    • Não sei explicar exatamente por quê, mas acho texto sem data um problema sério. Não sei se isso é uma tendência hoje em dia, mas sem data dá muito facilmente para confundir com um texto antigo. Às vezes tento deduzir o ano por timestamps deixados nos comentários, mas muitos blogs nem suportam comentários, então isso me desanima de voltar. (É irônico que na página principal do OP esteja escrito “não sou obcecado por detalhes”, quando na prática parece ter focado só na estética do design e deixado a funcionalidade de lado)

    • Quando o texto não tem data, eu tento usar o cabeçalho Last-Modified ao baixar o HTML por HTTP. Mas muitas vezes o autor nem se preocupa com isso. Pelo próprio nome blog, ou seja, [web]-log, dá para ver que timestamp era um elemento central, e parece que isso não é mais entendido. Só para constar, o valor de Last-Modified indica a última vez que aquele recurso (o HTML) foi modificado. Se o servidor não estiver configurado com cache e fizer re-render no backend a cada requisição, a data acaba sempre sendo atualizada
      Exemplo desse problema

    • Em grande parte é por SEO, para evitar que conteúdo antigo perca ranking nos mecanismos de busca. É um truque bem irritante

    • É por causa do Google e de SEO

  • O texto dizia que cores OKLCH produzem azuis mais consistentes em comparação com HSL, mas na prática a mudança de brilho em OKLCH desloca bastante para o verde. Manter a intensidade perceptual constante é com certeza uma vantagem, mas sinto que o efeito defendido aqui foi exagerado

    • Se você olhar o gráfico de hue dessa cor, dá para entender o motivo
      Gráfico de cores OKLCH
      Ao aumentar a luminosidade, você ultrapassa o limite da faixa de hue daquela cor, e por causa do limite de azuis claros que o display consegue reproduzir, a cor se desloca para Cyan. No OKLCH, ao ajustar a luminosidade em um gradiente, o que se mantém constante não é o hue, mas a saturation. Se esse efeito é bom ou não já entra no campo da preferência estética, mas depois de tanto tempo usando web colors dessaturadas com hue constante, acho interessante poder escolher qual compromisso adotar
      Discussão relacionada no Hacker News
      Cientistas inventaram recentemente LEDs azuis mais profundos, então espero que em 10 ou 20 anos, quando surgir uma tecnologia para substituir o Display P3, seja possível representar gradientes de azul mais fiéis sem esse deslocamento para Cyan. Até lá, o que fica bonito no design acaba sendo a resposta certa.
      Aliás, pensando em espaços de cor futuros, talvez em vez de tratar Hue e Saturation como uma escolha binária, fosse possível manter Saturation constante até o limite do display e, nesse ponto, passar gradualmente para Hue constante. Mas isso é muito difícil por causa das limitações dos perfis de cor (IDCv4). Ainda assim, seria divertido como alvo experimental no DisplayCAL

    • No meu display, não vejo nenhum green shift nesse exemplo. Fico me perguntando se sua tela não está com a calibração errada

    • Concordo. A cor muda completamente de azul para ciano. Se o OKLCH foi implementado corretamente, eu jamais iria querer usar isso. Parece haver algum problema sério no cálculo do hue. HSL/HSV têm problemas de lightness perceptual, mas o hue em si sempre fica constante, então não precisa de compensação

    • Não entendo muito de ciência das cores e isso pode ser subjetivo, mas a ponta direita dessa cor em OKLCH me parece, na pior das hipóteses, um blue-green ou simplesmente um light blue. Já as duas cores mais claras em HSL nem me parecem blue; a penúltima à direita lembra mais light purple e a última é quase cinza. A legenda dizia que o lado escuro do HSL era grayish, mas na prática tanto OKLCH quanto HSL têm blue no leftmost, ou seja, no lado mais escuro. Se medir com o Digital Color Meter do macOS, os valores de green no extremo direito de OKLCH e HSL são quase iguais (226 e 227; em sRGB, 228 e 227)

  • Recomendo um texto melhor sobre esse tema
    OKLCH in CSS: Why quit RGB, HSL, da Evil Martians
    Ferramenta de conversão de OKLCH para testar
    Discussão anterior no Hacker News (há 6 meses, 30 comentários)

  • OKLCH foi criado com base no OKLab (espaço de cor perceptualmente uniforme) e é um modelo para ajustar Lightness, Chroma e Hue. O “OK” vem do fato de o criador ter dito que “funciona razoavelmente bem”

    • Suspeito que o “OK” de OKLCH na verdade seja abreviação de “Ottossons kulör” (em sueco, “cor do Ottosson”). Pode ser que o criador tenha sido modesto e dito apenas OK
  • Ao trabalhar com cor e texto/logotipos, acho importante também considerar contraste e legibilidade
    APCA Contrast

    • Esse site é bom para usar o algoritmo de contraste mais recente (APCA, ainda não lançado oficialmente como algoritmo do futuro padrão WCAG 3), mas hoje muitas indústrias ainda seguem WCAG 2, então também é preciso prestar atenção às exigências legais.
      Verificador de contraste (WCAG 2)
      Também existem várias outras ferramentas
  • Na minha cabeça, o nome OKLCH virou naturalmente “Oklachroma”

  • Existe um post de blog original apresentando o espaço de cor OKLab, e ele é interessante do ponto de vista histórico
    Post original sobre OKLab

  • Fico me perguntando por que a fórmula de conversão para o espaço de cor OKLCH não está documentada. Se procurar no Google, só aparece um Gist[0], enquanto existe uma página da Wikipedia para Oklab[1]
    Exemplo de fórmula de conversão em Gist
    Wikipedia do Oklab

    • O núcleo da conversão está na matriz entre Oklab e sRGB. A conversão entre OKLab e OKLCH em si é apenas uma transformação de coordenadas, e isso já aparece na Wikipedia

    • OKLCH e OKLab são o mesmo espaço de cor. A diferença é só a forma de representação: coordenadas cartesianas (OKLab) vs. coordenadas polares (OKLCH)