- La paleta de colores existente de Postmark tenía una luminosidad percibida inconsistente según el color, y era difícil predecir la relación de contraste entre niveles, así que había que verificar manualmente cada vez el contraste recomendado por WCAG
- HSL/HSV son modelos derivados de una conversión simple de RGB, por lo que no reflejan la percepción humana de brillo y saturación; pueden servir para elegir un color aislado, pero no son adecuados para construir un sistema de color
- CIELAB y LCh son espacios de color perceptualmente uniformes diseñados para que los cambios numéricos se parezcan más a los cambios percibidos, por lo que permiten crear escalas de color con el mismo nivel de luminosidad de forma más consistente
- Accessible Palette es una app basada en LCh que genera una paleta consistente ajustando luminosidad, relación de contraste, corrección de tono e incorporación de colores de marca existentes
- Conviene revisar tanto la relación de contraste de WCAG 2.1 como APCA del Working Draft de WCAG 3 para poder responder tanto al cumplimiento actual de las pautas como a futuros cambios en el algoritmo de contraste
El problema del sistema de color de Postmark
- La paleta existente de Postmark tenía dos problemas
- La luminosidad percibida no era consistente: por ejemplo, el azul y el rojo se veían mucho más oscuros que el amarillo y el verde
- Era difícil predecir la relación de contraste entre variaciones de color, por lo que no era fácil saber si un par de colores cumplía las recomendaciones de WCAG
- Cada vez que se elegía un par de colores había que comprobar manualmente la relación de contraste, y en la práctica era muy posible que no se revisara
- La causa estaba en las limitaciones propias del modelo de color HSL y en que las herramientas de diseño no daban suficiente soporte a alternativas mejores
Por qué HSL no sirve para un sistema de color
- RGB es un modelo que refleja cómo funcionan las pantallas, pero no es un modelo intuitivo para que las personas elijan colores
- HSL y HSV/HSB son alternativas creadas en los años 70 para representar RGB de una manera más cercana a cómo las personas piensan el color
- HSL significa Hue, Saturation, Lightness
- HSV/HSB significa Hue, Saturation, Value o Brightness
- En ese momento, el costo computacional de modelos más sofisticados era alto, así que HSL y HSV sacrificaron precisión perceptual a cambio de velocidad de cálculo
- Como resultado, HSL y HSV no son más que transformaciones matemáticas simples de RGB y no reflejan correctamente cómo las personas perciben el brillo o la saturación
- Por ejemplo, en HSL una escala de colores ajustada con Saturation 100 y Lightness 50 tiene la misma luminosidad según el modelo, pero en realidad el azul
#00Fse ve mucho más oscuro que el amarillo#FF0o el cian#0FF - En HSL, los colores totalmente saturados se asignan a los valores máximos de RGB y se ubican en el círculo de Hue con Lightness 50, mientras que Lightness 0 y 100 corresponden a negro y blanco, respectivamente
- Las variaciones más claras u oscuras se crean “mezclándose” con blanco o negro
- El eje vertical central es el rango de colores neutros o grises con Saturation 0
CIELAB y LCh
- Cuando se formalizaron HSL y HSV, ya existía una alternativa mejor: el espacio de color CIELAB
- La International Commission on Illumination, es decir, la CIE, definió en 1976 el espacio de color CIELAB o L*a* b*
- CIELAB es un espacio de color perceptualmente uniforme diseñado para que cambios numéricos similares correspondan a cambios de color percibidos también similares
- A diferencia de RGB, fue diseñado para abarcar toda la gama de colores visibles
- El componente L*, que representa la luminosidad, está ajustado para acercarse a la percepción humana del brillo
- CIELAB se compone de tres ejes
- El valor L* define 0 como negro y 100 como blanco
- El eje a* es el eje de color opuesto verde-rojo: los valores negativos van hacia verde y los positivos hacia rojo
- El eje b* es el eje de color opuesto azul-amarillo: los valores negativos van hacia azul y los positivos hacia amarillo
- CIELCh, LCh o Lch(ab) es la representación cilíndrica de CIELAB
- En lugar de a* y b*, usa Chroma y un ángulo de Hue
- Lightness se mantiene igual
- El ángulo de Hue de LCh se parece al Hue de HSL, pero no es idéntico
- HSL/HSV colocan los tres primarios aditivos rojo, verde y azul en H=0, 120 y 240°
- LCh coloca rojo, amarillo, verde y azul en h=0, 90, 180 y 270°
- También existe un espacio similar llamado HCL o LCh(uv), que a diferencia de LCh(ab) tiene una escala uniforme de Chroma de 0 a 100
Cómo se construyen escalas de color en LCh
- A diferencia de HSL/HSV, LCh encaja dentro de un cilindro, pero no lo llena por completo
- Algunas combinaciones de Lightness, Chroma y Hue producen colores que no pueden existir
- Por ejemplo, no existe un amarillo oscuro y muy saturado
- A medida que una escala de luminosidad se acerca al negro o al blanco, disminuye la cantidad de colores que las personas pueden distinguir
- Las pantallas reales no pueden mostrar toda la gama de colores visibles
- La gama sRGB representa las pantallas comunes y solo incluye alrededor de ⅓ del espacio de color LCh
- En CSS también estamos limitados a ese rango, al menos por ahora
- Si se observa en términos de LCh una escala de colores de HSL con Saturation 100 y Lightness 50, el amarillo resulta ser el más claro y el azul el más oscuro
- El verde es casi tres veces más claro que el azul y alrededor de dos veces más claro que el rojo
- Si se vuelve a construir la escala en LCh con el mismo nivel de Lightness, la luminosidad entre colores se ve visualmente consistente
- Como Chroma varía, algunos colores pueden estar más saturados que otros
- En colores de aviso y alerta puede ser deseable una saturación mayor que en el color base del texto, así que esta diferencia puede ser útil en un sistema de color
- Si además se ajusta Chroma de manera más consistente, se pueden crear escalas suaves incluso dentro del espacio sRGB limitado
Limitaciones de las herramientas de diseño y Accessible Palette
- Actualmente, Figma, Sketch y Adobe XD no soportan CIELAB ni LCh
- En Figma existen los plugins LCH color picker y Chromatic, pero no eran suficientes para crear un sistema de color flexible
- La herramienta necesaria debía cumplir tres condiciones
- Mantener consistencia de luminosidad al crear variaciones de color
- Permitir controlar la relación de contraste entre niveles
- Ser lo bastante flexible para incorporar colores de marca ya existentes
- Después de encontrar la librería Chroma.js, que ofrece buen soporte para LCh, se creó una herramienta simple para generar una nueva paleta mediante código
- Tras usarla internamente y compartirla con algunas personas cercanas, la herramienta se publicó como la app Accessible Palette
- Accessible Palette es una app para crear sistemas de color con luminosidad consistente y relaciones de contraste predecibles a lo largo de todos los niveles de color
Cómo funciona Accessible Palette
- Al ajustar un color inicial o pegar un color de un diseño existente, la herramienta usa el Chroma y el Hue de ese color para calcular una escala con varios niveles de Lightness
- Lightness es totalmente personalizable y puede usarse tanto en paletas claras como oscuras
- Puede ajustarse con precisión para incluir colores de marca existentes
- En Postmark se buscó conservar el amarillo
#FFDE00, el azul#007DCCy el verde#4FC47F, que eran los más usados de la paleta anterior - Los valores de Lightness de esos colores, 88.6, 75.2 y 50.6, se usaron como la luminosidad de los niveles 200, 400 y 600, respectivamente
- La relación de contraste cambia según Lightness, y para cada nivel se calcula tanto con el método recomendado por WCAG 2.1 como con el nuevo algoritmo del Working Draft de WCAG 3.0
- Por defecto, el contraste de todos los colores se mide contra un fondo blanco
- Se puede elegir la muestra de color deseada para medir la relación de contraste tomando ese color como referencia
- Los niveles pueden generarse usando el espacio de color RGB o CIELAB
- En algunos casos los resultados pueden variar, así que vale la pena experimentar
- En el sistema de color de Postmark, usar CIELAB redujo el matiz púrpura de los rojos claros, pero aumentó ese matiz en los azules
- Algunos colores pueden necesitar corrección de Hue a lo largo de toda la escala
- El amarillo claro tiende a adquirir un matiz verdoso a medida que se oscurece
- Para acercarlo un poco más al naranja se usa una corrección negativa de Hue
- La app actualiza la URL mientras se usa para guardar los cambios
- Luego puede compartirse con el equipo o añadirse a una biblioteca de Figma y a un archivo de variables de color CSS para consultarlo después
- Como paletas de ejemplo, hay una basada en la nueva paleta de color de Postmark, otra inspirada en Material Design de Google y otra basada en TailwindCSS
- Estos ejemplos no son una réplica exacta de los originales, sino alternativas inspiradas en sus colores y niveles de luminosidad
Cálculo de contraste y WCAG
- Accessible Palette muestra dos relaciones de contraste porque el método de WCAG 2.1 tiene limitaciones
- WCAG 2.1 calcula la relación de contraste dividiendo la luminancia del color de primer plano entre la luminancia del color de fondo
- Esa fórmula ofrece una respuesta lineal, pero las personas perciben un contraste mayor entre colores claros que entre colores oscuros
- En ejemplos reales, una muestra que cumple las recomendaciones de WCAG 2.1 puede resultar más difícil de leer que otra marcada con contraste “insuficiente”
- El W3C reconoce este problema, y Andrew Somers inició una discusión pública en 2019
- El nuevo algoritmo de trabajo propuesto por Andrew Somers pasó a formar parte del Working Draft de WCAG 3, y también se creó la APCA Contrast Calculator
- APCA significa Advanced Perceptual Contrast Algorithm; es perceptualmente más preciso y también considera el tamaño y grosor de la tipografía
- Accessible Palette usa APCA y toma una puntuación de 60 como nivel mínimo recomendado para texto legible
- Ese umbral es similar a la recomendación tradicional de contraste 4.5:1 de WCAG 2.1
- La relación de contraste de WCAG 2.1 no es totalmente inútil
- En colores de rango medio sigue siendo bastante precisa
- Pero, en general, el nuevo algoritmo representa una mejora importante
- El método de WCAG 3 sigue siendo un Working Draft, así que puede cambiar con el tiempo
- Si se quiere construir un sistema de color pensando tanto en el cumplimiento actual como en la adaptación a cambios futuros, conviene tener presentes ambas guías a la vez
1 comentarios
Opiniones en Hacker News
En los sistemas comunes de visualización e impresión, hay que considerar que los rojos y azules saturados son, en realidad, más oscuros que el verde.
La fórmula exacta varía según el espacio de color, pero se suele citar
Grayscale = 0.299R + 0.587G + 0.114B; en ese caso, el rojo puro más brillante tiene alrededor de 30% de luminosidad y el azul puro 11%, así que en la mayoría de los casos rojo brillante es casi una contradicción.Se pueden usar esos colores, pero inevitablemente se verán oscuros; y si solo aplicas reglas de contraste, puedes cumplir con accesibilidad, pero si también quieres un resultado atractivo, las técnicas tratadas en el artículo son mucho más convenientes.
Incluso al crear fotografías estereoscópicas rojo-cian como https://en.wikipedia.org/wiki/Anaglyph_3D, los árboles y el pasto son verdes, pero en realidad tienen bastante componente rojo, lo que da un buen balance de canales y hace que tanto el efecto 3D como el color salgan bien.
Referencia: https://www.dynamsoft.com/blog/insights/image-processing/ima...
Siempre era difícil explicar que una hermosa pieza gráfica roja no se iba a ver nada hermosa en TV, y más aún si era para transmisión.
Incluso si no era para transmisión, los rojos fuera de especificación podían quedar visibles varios fotogramas después y verse como una mancha, como si hubiera un corte en el cuello.
Si leíste las respuestas, contéstame y puedo intentar aclarar algunas más.
Desde hace mucho me molestaba que las muestras que en realidad cumplen con el criterio recomendado de WCAG 2.1 sean más difíciles de leer que las muestras con una relación de contraste “insuficiente”.
Me pregunto por qué se estandarizó una fórmula de “pautas de accesibilidad” que más bien produce el efecto contrario.
Pasa con 2.1 y también con el próximo estándar; para un área con tanta influencia, me gustaría que la industria patrocinara investigaciones más rigurosas.
Tal vez simplemente existía esa demanda, pero todavía no se adoptó oficialmente.
El mejor texto que vi sobre este tema es https://www.handprint.com/HP/WCL/color1.html.
Es larguísimo, así que hay que prepararse para dedicarle un día.
Puede sorprender, pero en ClickHouse también usamos algunas ideas de ese texto para colorear bonito los logs: https://github.com/ClickHouse/ClickHouse/blob/master/base/ba...
Me pregunto si podrías compartir cuáles son los valores RGB esperados para cada tipo de mensaje configurado en el código.
Conocí a Eugene en Config, la conferencia de Figma; les dio a los diseñadores muchos consejos prácticos similares, y era una persona muy amable y realmente comprometida con el diseño y la accesibilidad.
Lo que quiero destacar especialmente de este artículo es APCA, que probablemente suceda al algoritmo de contraste de color de WCAG 2.
También usamos APCA en la renovación interna de accesibilidad de Figma, y gracias a eso el resultado final fue mucho mejor.
Eugene muestra muy bien los casos en que WCAG 2 falla, y en la práctica nosotros también nos topábamos con esos casos continuamente.
El consejo clave es que ajustar bien los colores es realmente difícil.
Las herramientas ayudan, pero en algún momento hay que confiar en los ojos.
Al final, estas herramientas solo aproximan matemáticamente la forma en que el ojo ve el color, y el criterio final no es el algoritmo sino el ojo humano.
Cuando una herramienta o algoritmo produce resultados que no cuadran, conviene ajustar o volver a lo básico.
Quisiera entender si significa que usaron solo APCA e ignoraron lo que el algoritmo de contraste de color de WCAG 2 marcaba como contraste insuficiente.
Está muy bien hecho.
También quiero presentar HCT
Es un espacio de color creado para hacer posible Material You, que combina la medición de luminosidad mencionada aquí con un espacio de color moderno basado en la ciencia del color
LAB/LCH viene de 1976
Hace que el diseño sea más intuitivo: solo hay que saber que una diferencia de
Tde 40 cumple el criterio de WCAG para botones, y una de 50 cumple el criterio para textoMe da curiosidad cómo se compara HCT con https://www.hsluv.org/comparison/
De forma similar a HCT, aquí se vuelve más fácil elegir colores con contraste usando la diferencia de
LEn la misma línea, también me interesa qué piensan de https://www.myndex.com/APCA/ y del enfoque que se adoptará cuando eso se convierta en estándar
Como el valor de contraste entre dos colores cambia según cuál sea el primer plano y cuál el fondo, parece que ya no bastará con comparar solo la diferencia de
TPor ejemplo, supongamos que una aplicación necesita rojo, amarillo, azul, naranja, verde y morado; es decir, 6 colores que correspondan a 3 primarios y 3 complementarios
No importa demasiado cuáles sean exactamente esos colores, pero si quisiera que esos 6 fueran más o menos distinguibles y que tuvieran luminosidad, y quizá hasta saturación, similares, ¿cómo debería hacerlo?
El amarillo es muy claro y el azul es muy oscuro, así que parece que no hay una respuesta exacta y habría que llegar a una aproximación
Me pregunto si hay alguna herramienta o tutorial para aprender esto
Lo único que encontré fue el código de
material-color-utilitiesen GitHubAl ver el código, los cálculos parecen mucho más complejos que OkLab, especialmente la conversión de HCT a RGB
Además de que el artículo omite oklab/oklch, también es falsa la afirmación de que la web/CSS solo soporta sRGB
La función CSS
color()soporta varios espacios de colorEste artículo se publicó hace 2 años y, cuando empecé a trabajar en la herramienta, la especificación de OkLCH todavía ni siquiera había salido
Si fuera hoy, elegiría OkLCH en lugar de LCH, porque resuelve varios problemas de LCH
Aquí, “soportado” sería más precisamente algo como “soportado excepto en Microsoft Edge(chromium) y Pale Moon(goanna)”
https://test.csswg.org/harness/results/css-color-4_dev/group...
Pero usa la razón de contraste de APCA, es decir, de WCAG 3, en lugar de la luminosidad: https://github.com/antiflasher/apcach
oklab podría ser una alternativa mejor que LCh
https://bottosson.github.io/posts/oklab/
El canal de luminosidad está invertido respecto de todos los demás espacios de color, y
Lno tiene nada que ver con laLde LCH o LABSu éxito incluso trajo consigo cierta pobreza intelectual
El primer post del blog tiene muchísimas cosas que habría que corregir, y la lógica se descarrila bastante desde el punto en que empieza a afirmar exactitud con gradientes usando CAM16 UCS
Si los valores de CIELAB se basan en cambios perceptivos, me pregunto cómo interactúan con la accesibilidad
¿Deberíamos preocuparnos de que estas fórmulas perceptivas probablemente se hayan creado con base en visión estándar?
También me pregunto si podría variar según el tipo de deficiencia en la percepción del color, o si no es ese tipo de problema
Intento hacer que mis gráficas sean lo más accesibles posible, pero nunca aprendí nada sobre color, así que solo sigo consejos y no puedo derivarlos por mi cuenta
Así que es muy posible que sea una pregunta tonta
El contraste cambia de forma no lineal
Las simulaciones se pueden aplicar con bastante facilidad, y la simulación de Machado y otros autores no es más que una transformación matricial
El artículo deja la explicación hacia el final, pero APCA Contrast, la prueba de contraste legible del borrador del estándar WCAG 3, es mucho más justa que la razón de contraste de WCAG 2.1 para algunos colores
Un artículo fácil de leer sobre la teoría del color detrás del contraste perceptivo: https://www.smashingmagazine.com/2022/09/realities-myths-con...
Un artículo que explica APCA de forma concisa: https://typefully.com/u/DanHollick/t/sle13GMW2Brp
Antes de usarlo para cualquier cosa, conviene revisar esa parte en detalle y decidir si realmente se puede usar
¿Dónde está el código?
No hace falta un formulario web, sino un algoritmo que pueda usarse en cualquier software.
La probé directamente y funcionó bien.
https://github.com/gka/chroma.js
Oklab se presentó en [2], y el código de ese artículo es realmente fácil de usar.
[1]: https://news.ycombinator.com/item?id=37310534
[2]: https://bottosson.github.io/posts/oklab/