Paleta acessível: pare de usar HSL em sistemas de cores
(wildbit.com)- A paleta de cores antiga da Postmark tinha luminosidade percebida inconsistente entre as cores, e era difícil prever a taxa de contraste entre os níveis, então era preciso verificar manualmente a conformidade com o contraste recomendado pela WCAG toda vez
- HSL/HSV são modelos derivados de uma simples transformação de RGB, então não refletem a percepção humana de luminosidade e saturação; podem servir para escolher uma única cor, mas não são adequados para construir um sistema de cores
- CIELAB e LCh são espaços de cor perceptualmente uniformes projetados para que mudanças numéricas se aproximem mais das mudanças percebidas, permitindo criar escalas de cores com o mesmo nível de luminosidade de forma mais consistente
- Accessible Palette é um app que gera paletas consistentes com base em LCh, ajustando luminosidade, taxa de contraste, correção de Hue e incorporação das cores de marca existentes
- É importante verificar juntos a taxa de contraste da WCAG 2.1 e a APCA do Working Draft da WCAG 3 para lidar tanto com a conformidade atual quanto com futuras mudanças no algoritmo de contraste
O problema no sistema de cores da Postmark
- A paleta antiga da Postmark tinha dois problemas
- A luminosidade percebida não era consistente; por exemplo, azul e vermelho pareciam muito mais escuros do que amarelo e verde
- Era difícil prever a taxa de contraste entre variações de cor, então não dava para saber facilmente se um par de cores atendia às recomendações da WCAG
- Era necessário verificar manualmente a taxa de contraste sempre que se escolhia um par de cores, e na prática havia grande chance de essa verificação nem acontecer
- A causa estava nas limitações do próprio modelo de cores HSL e no fato de as ferramentas de design não oferecerem suporte suficiente a alternativas melhores
Por que HSL não serve para sistemas de cores
- RGB é um modelo que reflete a forma como as telas funcionam, mas não é um modelo intuitivo para pessoas escolherem cores
- HSL e HSV/HSB são alternativas criadas nos anos 1970 para representar RGB de um jeito mais próximo da forma como as pessoas pensam em cor
- HSL significa Hue, Saturation, Lightness
- HSV/HSB significa Hue, Saturation, Value ou Brightness
- Na época, o custo computacional de modelos mais sofisticados era alto, então HSL e HSV sacrificaram a precisão perceptual em favor da velocidade de cálculo
- Como resultado, HSL e HSV são apenas transformações matemáticas simples de RGB e não refletem adequadamente a luminosidade ou a saturação percebidas pelas pessoas
- Por exemplo, em HSL, uma escala de cores definida com Saturation 100 e Lightness 50 tem a mesma luminosidade no modelo, mas na prática o azul
#00Fparece muito mais escuro do que o amarelo#FF0ou o ciano#0FF - Em HSL, cores totalmente saturadas são mapeadas para os valores máximos de RGB e ficam no círculo de Hue de Lightness 50, enquanto Lightness 0 e 100 correspondem a preto e branco, respectivamente
- Variações mais claras ou mais escuras são geradas de forma parecida com uma “mistura” com branco ou preto
- O eixo vertical central representa as cores neutras, ou a faixa de cinzas, com Saturation 0
CIELAB e LCh
- Quando HSL e HSV estavam sendo formalizados, já existia uma alternativa melhor: o espaço de cores CIELAB
- A International Commission on Illumination, ou CIE, definiu em 1976 o espaço de cores CIELAB, também chamado de L*a* b*
- CIELAB é um espaço de cor perceptualmente uniforme projetado para que mudanças numéricas correspondam a mudanças de cor percebidas de forma semelhante
- Ao contrário de RGB, ele foi projetado para abranger toda a faixa de cores visíveis
- O componente L*, de Lightness, foi ajustado para se aproximar da percepção humana de luminosidade
- CIELAB é composto por três eixos
- O valor L* define preto em 0 e branco em 100
- O eixo a* é o eixo de cores opostas verde-vermelho; valores negativos apontam para verde e positivos para vermelho
- O eixo b* é o eixo de cores opostas azul-amarelo; valores negativos apontam para azul e positivos para amarelo
- CIELCh, LCh ou Lch(ab) é a representação cilíndrica de CIELAB
- Em vez de a* e b*, usa Chroma e ângulo de Hue
- Lightness é mantido
- O ângulo de Hue em LCh é parecido com o Hue de HSL, mas não é igual
- HSL/HSV colocam as três primárias aditivas vermelho, verde e azul em H=0, 120, 240°
- LCh coloca vermelho, amarelo, verde e azul em h=0, 90, 180, 270°
- Também existe um espaço semelhante chamado HCL ou LCh(uv), que, ao contrário de LCh(ab), tem uma escala uniforme de Chroma de 0 a 100
Como criar escalas de cores em LCh
- Ao contrário de HSL/HSV, LCh cabe dentro de um cilindro, mas não o preenche completamente
- Algumas combinações de Lightness, Chroma e Hue resultam em cores que não podem existir
- Por exemplo, amarelo escuro e altamente saturado não existe
- À medida que se aproxima do preto e do branco em uma escala de Lightness, o número de cores que as pessoas conseguem distinguir diminui
- Telas reais não conseguem exibir toda a gama de cores visíveis
- O gamut sRGB representa telas comuns e inclui apenas cerca de ⅓ do espaço de cores LCh
- Em CSS, pelo menos por enquanto, o limite também é esse intervalo
- Se uma escala de cores com Saturation 100 e Lightness 50 em HSL for vista a partir da referência de LCh, o amarelo é o mais claro e o azul o mais escuro
- O verde é quase três vezes mais claro que o azul e cerca de duas vezes mais claro que o vermelho
- Quando a escala é refeita em LCh com o mesmo nível de Lightness, a luminosidade entre as cores fica visualmente consistente
- Como o Chroma varia, algumas cores podem ficar mais saturadas do que outras
- Cores de aviso e alerta podem precisar ser mais saturadas do que a cor de texto padrão, então essa diferença pode ser útil em um sistema de cores
- Se o Chroma também for ajustado com mais consistência, dá para criar escalas suaves mesmo dentro do espaço sRGB limitado
Limitações das ferramentas de design e o Accessible Palette
- Atualmente, Figma, Sketch e Adobe XD não oferecem suporte a CIELAB nem LCh
- O Figma tem os plugins LCH color picker e Chromatic, mas eles não eram suficientes para criar um sistema de cores flexível
- A ferramenta necessária precisava atender a três condições
- Manter consistência de luminosidade ao criar variações de cor
- Permitir controlar a taxa de contraste entre os níveis
- Ser flexível o suficiente para acomodar as cores de marca existentes
- Depois de encontrar a biblioteca Chroma.js, que tem bom suporte a LCh, foi criada uma ferramenta simples para gerar a nova paleta por código
- Após uso interno e compartilhamento com algumas pessoas próximas, essa ferramenta foi lançada como o app Accessible Palette
- Accessible Palette é um app para criar sistemas de cores com luminosidade consistente e taxa de contraste previsível ao longo dos níveis de cor
Como o Accessible Palette funciona
- Ao ajustar uma cor inicial ou colar uma cor de um design existente, a ferramenta usa o Chroma e o Hue dessa cor para calcular uma escala com vários níveis de Lightness
- Lightness é totalmente personalizável e pode ser usado tanto em paletas claras quanto escuras
- Dá para ajustar com precisão para incluir cores de marca existentes
- Na Postmark, tentou-se preservar o amarelo
#FFDE00, o azul#007DCCe o verde#4FC47F, que eram as cores mais usadas da paleta antiga - Os valores de Lightness dessas cores, 88.6, 75.2 e 50.6, foram usados como os brilhos dos níveis 200, 400 e 600, respectivamente
- A taxa de contraste varia conforme o Lightness e é calculada para cada nível usando tanto o método recomendado pela WCAG 2.1 quanto o novo algoritmo do Working Draft da WCAG 3.0
- Por padrão, o contraste de todas as cores é medido em relação a um fundo branco
- É possível escolher a amostra de cor desejada e medir a taxa de contraste em relação a ela
- Os níveis podem ser gerados usando os espaços de cor RGB ou CIELAB
- Em alguns casos, os resultados podem variar, então vale experimentar
- No sistema de cores da Postmark, usar CIELAB reduziu o tom arroxeado nos vermelhos claros, mas aumentou esse tom nos azuis
- Algumas cores podem exigir correção de Hue ao longo de toda a faixa
- Amarelos claros tendem a ganhar um tom esverdeado à medida que escurecem
- Para aproximá-los um pouco mais do laranja, usa-se uma correção negativa de Hue
- O app atualiza a URL durante o uso para salvar as alterações
- Isso permite compartilhar com a equipe ou adicionar depois à biblioteca do Figma e a arquivos de variáveis de cor em CSS para referência futura
- Entre as paletas de exemplo estão a nova paleta de cores da Postmark, alternativas baseadas no Material Design do Google e no TailwindCSS
- Esses exemplos não reproduzem exatamente os originais; são alternativas inspiradas nas cores e nos níveis de luminosidade das versões originais
Cálculo de contraste e WCAG
- O Accessible Palette mostra duas medidas de contraste porque o método da WCAG 2.1 tem limitações
- A WCAG 2.1 calcula a taxa de contraste dividindo a luminância da cor de primeiro plano pela luminância da cor de fundo
- Essa fórmula fornece uma resposta linear, mas as pessoas percebem o contraste entre cores claras como maior do que o contraste entre cores escuras
- Em exemplos reais, uma amostra que atende às recomendações da WCAG 2.1 pode ser mais difícil de ler do que outra marcada como contraste “insuficiente”
- O W3C reconhece esse problema, e Andrew Somers iniciou uma discussão pública em 2019
- O novo algoritmo de trabalho proposto por Andrew Somers passou a fazer parte do Working Draft da WCAG 3, e ele também criou a APCA Contrast Calculator
- APCA significa Advanced Perceptual Contrast Algorithm, é perceptualmente mais precisa e também leva em conta o tamanho e o peso da fonte
- Accessible Palette usa APCA e considera a pontuação 60 como o nível mínimo recomendado para texto legível
- Isso corresponde aproximadamente à recomendação tradicional de contraste 4.5:1 da WCAG 2.1
- Isso não significa que a taxa de contraste da WCAG 2.1 seja totalmente inútil
- Em cores de faixa intermediária, ela ainda é razoavelmente precisa
- Mas, no geral, o novo algoritmo representa uma grande melhora
- Como o método da WCAG 3 ainda está em Working Draft, ele pode mudar com o tempo
- Para conciliar a conformidade com as diretrizes atuais e a adaptação a mudanças futuras, o ideal é criar sistemas de cores levando as duas orientações em consideração
1 comentários
Comentários do Hacker News
Em sistemas comuns de display e impressão, é preciso considerar que vermelhos e azuis saturados são, na prática, mais escuros que o verde
Dependendo do espaço de cor, a fórmula exata muda, mas
Grayscale = 0.299R + 0.587G + 0.114Bé frequentemente citada; nesse caso, o vermelho puro mais brilhante tem cerca de 30% de luminosidade, e o azul puro, 11%, então, na maioria dos casos, vermelho claro é quase uma contradiçãoÉ possível usar essas cores, mas elas inevitavelmente vão parecer escuras; e, se você apenas aplicar regras simples de contraste, pode até atender à acessibilidade, mas, se também quiser um resultado bonito, as técnicas tratadas no artigo são muito mais vantajosas
Ao criar imagens 3D anáglifas em vermelho-ciano, como em https://en.wikipedia.org/wiki/Anaglyph_3D, árvores e grama são verdes, mas, na prática, têm muito componente vermelho, então o equilíbrio entre canais fica bom e tanto a sensação de profundidade quanto as cores saem bem
Referência: https://www.dynamsoft.com/blog/insights/image-processing/ima...
Sempre foi difícil explicar que uma arte vermelha linda não ficaria nada bonita na TV, especialmente se fosse para broadcast
Mesmo quando não era para broadcast, um vermelho fora da especificação podia ficar visível por alguns frames depois e parecer borrado, como uma garganta cortada
Se você leu as respostas, posso responder e tentar esclarecer mais alguns pontos
Há muito tempo me incomoda que, na prática, uma amostra que atende ao critério recomendado da WCAG 2.1 seja mais difícil de ler do que uma amostra com taxa de contraste “insuficiente”
Fico curioso por que a fórmula das “diretrizes de acessibilidade” foi padronizada se ela acaba tendo o efeito oposto
Isso vale para a 2.1 e também para o próximo padrão; para uma área com tanta influência, eu gostaria que o setor financiasse pesquisas mais rigorosas
Talvez tenha sido apenas uma demanda desse tipo e ainda não tenha sido adotada oficialmente
O melhor texto que já vi sobre esse tema é https://www.handprint.com/HP/WCL/color1.html
É um texto enorme, então é bom estar preparado para gastar um dia com ele
Pode parecer surpreendente, mas também usamos algumas ideias desse texto para colorir logs de forma bonita no ClickHouse: https://github.com/ClickHouse/ClickHouse/blob/master/base/ba...
Fico curioso se você poderia compartilhar quais valores RGB são esperados no código para cada tipo de mensagem configurado
Conheci Eugene na conferência Config da Figma; ele deu muitas dicas práticas parecidas para designers, e era uma pessoa muito gentil e realmente comprometida com design e acessibilidade
O que eu quero elogiar especialmente neste artigo é o APCA, que tem grandes chances de suceder o algoritmo de contraste de cores da WCAG 2
Também usamos o APCA na reformulação interna de acessibilidade da Figma, e isso deixou o resultado final muito melhor
Eugene mostra bem os casos em que a WCAG 2 falha, e nós também nos deparamos com esses casos repetidamente
O conselho central é que acertar as cores de verdade é muito difícil
Ferramentas ajudam, mas, em algum momento, você precisa confiar nos seus olhos
No fim, essas ferramentas apenas aproximam matematicamente a forma como os olhos percebem cores, e o critério final não é o algoritmo, mas o olhar humano
Nos pontos em que uma ferramenta ou algoritmo produzir um resultado inadequado, é melhor ajustar ou voltar ao básico
Quero entender se isso significa que vocês usaram apenas o APCA e ignoraram os conteúdos que o algoritmo de contraste de cores da WCAG 2 marcava como contraste insuficiente
Ficou muito bem feito
Também quero apresentar o HCT
É um espaço de cores criado para viabilizar o Material You, combinando a medida de luminosidade mencionada aqui com um espaço de cores moderno baseado na ciência das cores
LAB/LCH surgiu em 1976
Ele torna o design mais intuitivo: basta saber que uma diferença de
Tde 40 atende aos critérios WCAG para botões, e de 50 atende aos critérios para textoFico curioso para saber como o HCT se compara a https://www.hsluv.org/comparison/
De forma parecida com o HCT, aqui fica mais fácil escolher cores com contraste usando a diferença de
LNo mesmo contexto, também tenho curiosidade sobre https://www.myndex.com/APCA/ e sobre qual seria a abordagem quando isso se tornar padrão
Como o valor de contraste entre duas cores muda dependendo de qual cor é o primeiro plano e qual é o fundo, parece que agora comparar apenas a diferença de
Ttalvez não seja suficientePor exemplo, digamos que uma aplicação precise de vermelho, amarelo, azul, laranja, verde e roxo — ou seja, 6 cores, correspondentes às 3 cores primárias e às 3 complementares
Não importa muito quais sejam exatamente essas cores, mas, se eu quiser que essas 6 sejam razoavelmente distinguíveis e tenham luminosidade, talvez até saturação, parecidas, como devo fazer?
Como o amarelo é muito claro e o azul é muito escuro, acho que não há uma resposta exata e seria preciso chegar a uma aproximação
Fico curioso se há alguma ferramenta ou tutorial para aprender esse tipo de coisa
O que encontrei foi apenas o código
material-color-utilitiesno GitHubOlhando o código, os cálculos parecem muito mais complexos que no OkLab, especialmente no caminho de HCT para RGB
Além de o texto ter deixado de fora oklab/oklch, a afirmação de que a Web/CSS só oferece suporte a sRGB também está errada
A função CSS
color()oferece suporte a vários espaços de coresEste texto foi publicado há 2 anos e, quando comecei a trabalhar na ferramenta, a especificação do OkLCH ainda nem existia
Hoje eu escolheria OkLCH em vez de LCH, porque ele resolve alguns problemas do LCH
Aqui, “suporte” seria mais precisamente algo como “suportado, exceto no Microsoft Edge (Chromium) e no Pale Moon (Goanna)”
https://test.csswg.org/harness/results/css-color-4_dev/group...
Só que ele usa a razão de contraste do APCA, isto é, do WCAG 3, em vez da luminosidade: https://github.com/antiflasher/apcach
oklab pode ser uma alternativa melhor que LCh
https://bottosson.github.io/posts/oklab/
O canal de luminosidade é invertido em relação a todos os outros espaços de cores, e
Lnão tem nenhuma relação com oLde LCH ou LABSeu sucesso, de certa forma, acabou trazendo mais empobrecimento intelectual
Há muita coisa no post original do blog que precisa ser corrigida, e a lógica desanda bastante a partir do ponto em que começa a reivindicar precisão usando gradientes com CAM16 UCS
Se os valores do CIELAB se baseiam em mudanças perceptuais, fico curioso para saber como isso interage com acessibilidade
Deveríamos nos preocupar com a possibilidade de essas fórmulas perceptuais terem sido criadas com base em visão padrão?
Também me pergunto se isso pode variar conforme o tipo de deficiência de visão de cores, ou se não é esse o problema
Tento tornar os gráficos o mais acessíveis possível, mas nunca aprendi nada sobre cores, então apenas sigo conselhos e não consigo derivar isso por conta própria
Portanto, há uma boa chance de esta ser uma pergunta boba
O contraste muda de forma não linear
As simulações são relativamente fáceis de aplicar, e a simulação de Machado e outros autores é apenas uma transformação matricial
O texto coloca a explicação mais abaixo, mas o APCA Contrast, o teste de contraste legível do rascunho do padrão WCAG 3, é muito mais justo para algumas cores do que a razão de contraste do WCAG 2.1
Um bom texto para ler sobre a teoria das cores por trás do contraste perceptual: https://www.smashingmagazine.com/2022/09/realities-myths-con...
Um texto que explica APCA de forma concisa: https://typefully.com/u/DanHollick/t/sle13GMW2Brp
Antes de usá-lo para qualquer coisa, é melhor examinar essa parte com atenção e decidir se você realmente pode usá-lo
Onde está o código?
Não preciso de um formulário web, mas sim de um algoritmo que possa ser usado em qualquer software
Eu mesmo a usei e funcionou bem
https://github.com/gka/chroma.js
Oklab foi apresentado em [2], e o código desse artigo é realmente fácil de usar
[1]: https://news.ycombinator.com/item?id=37310534
[2]: https://bottosson.github.io/posts/oklab/