CategoríaDiseño de producto
Modo oscuro no es invertir color: contraste en práctica
Modo oscuro no es inversión de color. Es una segunda elección de la escala de contraste, hecha con los mismos tokens y valores distintos. Un tema generado al voltear los valores del tema claro conserva la jerarquía anterior y pierde la separación entre capas. Por eso la inversión automática suele reprobar en la WCAG 2.2.
Por qué la inversión rompe la jerarquía
La razón de contraste mide una relación entre dos colores. No mide el lugar del color en la interfaz.
En el tema claro la página es la superficie más clara. La tarjeta queda encima con un valor apenas distinto, y el diálogo queda encima de la tarjeta. El orden de las superficies carga el significado.
Voltear los valores refleja ese orden. La tarjeta que se leía como elevada pasa a leerse como hundida, porque la superficie detrás es más oscura que ella misma. La razón entre los dos colores puede seguir igual mientras el significado del par cambia.
Jerarquía es relación entre superficies. La inversión mueve valores, no relaciones.
Qué exige la WCAG 2.2
Las Pautas de Accesibilidad para el Contenido Web en su versión 2.2 (en inglés) declaran tres umbrales de contraste. Cada uno aplica a un tipo de contenido.
- El Criterio de Conformidad 1.4.3 (en inglés), nivel AA, exige una razón de contraste de al menos 4,5 a 1 en texto y en imágenes de texto.
- El mismo criterio (en inglés) baja la exigencia a 3 a 1 en texto de escala grande. El glosario define escala grande como 18 puntos o más, o 14 puntos en negrita.
- El Criterio de Conformidad 1.4.11 (en inglés), nivel AA, exige 3 a 1 contra los colores adyacentes en componentes de interfaz y objetos gráficos.
- El Criterio de Conformidad 1.4.6 (en inglés), nivel AAA, sube la exigencia de texto a 7 a 1 y mantiene 4,5 a 1 en texto grande.
El documento de entendimiento del 1.4.3 (en inglés) trae la conversión. Un punto equivale a 1,333 píxeles CSS, así que 14 puntos son unos 18,5 píxeles y 18 puntos son unos 24 píxeles.
Dos detalles deciden la mayoría de las fallas. Los umbrales no se redondean, y 4,499 a 1 no cumple el 4,5 a 1. Y un componente sin texto y sin ícono necesita un borde visible en 3 a 1, porque el borde pasa a ser la única señal de que el control existe (WCAG 1.4.3 (en inglés), WCAG 1.4.11 (en inglés)).
Cómo medir el contraste
La razón de contraste es (L1 + 0,05) / (L2 + 0,05), donde L1 es la luminancia relativa del color más claro y L2 la del más oscuro. El glosario (en inglés) registra que el resultado va de 1 a 1 hasta 21 a 1.
La luminancia no es el promedio de los canales RGB. Una herramienta que promedia canales informa un número que la WCAG no usa.
El documento de entendimiento (en inglés) pide al autor leer los colores del marcado o de las hojas de estilo, no de la pantalla renderizada. El suavizado de bordes hace que el texto fino y la línea fina se vean más apagados que el color declarado.
Esa nota trae un aviso práctico. Una fuente fina puede pasar el cálculo y aun así leerse mal. El documento recomienda una fuente más pesada, o un par de colores que supere el umbral.
En degradado o foto detrás de texto, la orientación es probar el área de menor contraste, no el promedio. El esquema de color de la guía de Material Design y el contraste dentro de él son el tema de roles de color en Material.
Por qué la sombra no separa capas en oscuro
La sombra funciona oscureciendo una superficie respecto de la superficie detrás. Sobre un fondo oscuro queda poco espacio para oscurecer, así que la sombra pierde su trabajo.
Ese trabajo pasa a hacerlo el valor del propio fondo. En un tema oscuro una capa queda encima de la página cuando su fondo es más claro que la página, y debajo cuando es más oscuro. La elevación pasa a ser escala de claridad, no escala de sombra.
Esa escala tiene un límite. Cerca del negro, dos pasos de claridad son difíciles de distinguir, así que un tema que arranca en negro puro se queda sin espacio tras una o dos capas.
Carbon (en inglés), el sistema de diseño de IBM, documenta esto como modelo de capas (en inglés). Sus temas emparejan un tema claro, White o Gray 10, con un tema oscuro, Gray 100 o Gray 90. Las capas llevan nombre de posición, no de valor de color.
Los bordes y contornos cargan parte del trabajo. En oscuro, un borde fino en 3 a 1 contra las dos superficies sustituye la sombra que separaba la tarjeta en el tema claro (WCAG 1.4.11 (en inglés)).
Token de color contra valor suelto
Un token de color nombra un rol. Un valor suelto nombra un color. La diferencia decide cuánto cuesta cambiar el tema.
Carbon (en inglés) declara la regla en una línea. No se puede implementar modo claro y oscuro sin usar tokens de color en todo el producto, y un valor fijo no cambia cuando el modo cambia.
El token también carga la verificación. Cuando el fondo del botón es un token, el build lee el par de tokens y calcula la razón. Cuando el fondo es un literal, la revisión necesita ojo humano y captura de pantalla.
La prueba práctica es rápida. Busca valores hexadecimales fuera del archivo de tokens. Cada uno encontrado es un punto donde el tema oscuro puede fallar en silencio.
El token necesita un nombre que sobreviva al cambio de tema. Un token llamado gris-claro deja de significar algo en el tema oscuro. Un token llamado superficie-elevada conserva el sentido en los dos.
Cómo probar contraste en el build
La revisión de contraste pertenece al build, junto al lint y al chequeo de tipos. La revisión manual alcanza solo las pantallas que alguien recordó abrir.
El chequeo necesita tres entradas. Necesita los pares de tokens en uso, el fondo detrás de cada color de texto, y el tamaño y el peso del texto. El tamaño decide qué umbral aplica, ya que el texto grande baja de 4,5 a 1 a 3 a 1 (WCAG 1.4.3 (en inglés)).
El resultado es una lista, no un sí o no. La lista debe nombrar el par de tokens, la razón calculada, el umbral y el archivo que usa el par.
Dos reglas mantienen el chequeo correcto. No redondees la razón antes de comparar, porque la orientación trata 4,499 a 1 como falla. Y resuelve el fondo real, porque texto sobre tarjeta sobre página tiene dos candidatos y gana el más estricto (WCAG 1.4.3 (en inglés)).
Un chequeo que lee tokens cubre el cambio de tema. Un chequeo que lee una captura cubre un tema y un tamaño de pantalla.
La herramienta es secundaria. Cualquier script que convierta los valores de token a luminancia y aplique la fórmula sirve, y la fórmula es pública.
Foco y estado deshabilitado, donde el contraste escapa
El foco es el estado donde el contraste se pierde más seguido, porque el indicador vive en la frontera entre dos superficies.
El Criterio de Conformidad 1.4.11 cubre ese caso. Toda información visual necesaria para indicar estado, como seleccionado o enfocado, necesita 3 a 1 contra los colores adyacentes (WCAG 1.4.11 (en inglés)).
El Criterio de Conformidad 2.4.13 (en inglés), nivel AAA, agrega una medida. El indicador de foco debe cubrir al menos el área de un perímetro de 2 píxeles CSS del componente sin foco. El contraste entre el estado con foco y el sin foco debe llegar a 3 a 1.
La regla de colores adyacentes decide el caso difícil. Un anillo de foco dentro de la tarjeta debe contrastar con la tarjeta, y un anillo fuera debe contrastar con la página. Un anillo dibujado en la frontera puede reprobar en los dos.
El estado deshabilitado es la otra salida, y llega con excepción escrita. Los criterios 1.4.3 y 1.4.11 exceptúan los componentes de interfaz inactivos, así que un control gris no tiene exigencia de contraste.
La excepción no es una instrucción de diseño. Un control deshabilitado ilegible deja a la persona sin saber qué acción está bloqueada, y el documento de entendimiento (en inglés) registra que un control de bajo contraste puede pasar inadvertido.
Una regla que funciona es apagar el control deshabilitado menos de lo que te pide el instinto, y mantener la etiqueta por encima de la razón de un texto de cuerpo. La excepción quita la obligación, no el costo.
Dónde el modo oscuro empeora, y cuándo gana el claro
El modo oscuro no sale gratis. Su costo está documentado.
Carbon (en inglés) registra que el modo oscuro es mejor para personas con cataratas y trastornos relacionados. Además emite menos luz, lo que puede reducir la fatiga visual y el dolor de cabeza. La misma página (en inglés) registra que parte de la investigación muestra usuarios sin discapacidad visual rindiendo mejor en modo claro.
El texto largo es el punto débil. Una página de cuerpo de texto en color claro sobre fondo oscuro se lee peor que el mismo texto en el tema claro. Un peso de fuente fino lo empeora.
El tema claro es la elección correcta para lectura larga, para documentación, para formularios con muchos campos y para cualquier superficie que la persona mira durante una hora. El modo oscuro sirve para sesiones cortas, medios, código e interfaces usadas de noche.
Muchas veces la mejor respuesta es no elegir. Cuando los dos temas comparten el conjunto de tokens y ambos pasan el chequeo, la persona decide por preferencia y el build protege los dos lados.
Dónde discrepa Nielsen Norman Group
Los tres textos de Nielsen Norman Group no cuentan la misma historia, y vale mostrar dónde se separan.
El texto sobre modo oscuro (en inglés) revisa la literatura y relata que la polaridad negativa perjudica sobre todo a quien tiene visión normal. El texto sobre los problemas que reporta quien usa modo oscuro (en inglés) va más allá en otra dirección. Afirma que el efecto es mucho menor de lo que sugieren las afirmaciones. Y que parte de la investigación no encontró diferencia significativa en cansancio visual ni dolor de cabeza, con la luz del ambiente pesando tanto como el color. Los dos textos miden el mismo tema y llegan a tamaños de efecto distintos.
Los otros dos textos no son sobre un modo. El texto sobre bajo contraste (en inglés) es de 2015 y pide agrandar la fuente antes de bajar el contraste. El texto sobre legibilidad (en inglés) pide mantener alto contraste entre carácter y fondo. Los dos convergen contra el texto apagado, incluido el apagado del modo claro.
La posición de este post es la más estrecha. Mantiene la razón como vara medible y trata el modo como segunda escala, y no afirma que una polaridad gane para todo el mundo.
Fuentes
- W3C, Understanding Success Criterion 1.4.3: Contrast (Minimum) (en inglés)
- W3C, Understanding Success Criterion 1.4.6: Contrast (Enhanced) (en inglés)
- W3C, Understanding Success Criterion 1.4.11: Non-text Contrast (en inglés)
- W3C, Understanding Success Criterion 2.4.13: Focus Appearance (en inglés)
- W3C, Web Content Accessibility Guidelines (WCAG) 2.2 (en inglés)
- IBM, Carbon Design System, Color usage (en inglés)
- Nielsen Norman Group, Dark Mode (en inglés)
- Nielsen Norman Group, Dark Mode Users’ Issues (en inglés)
- Nielsen Norman Group, Low-Contrast Text (en inglés)
- Nielsen Norman Group, Legibility, Readability, and Comprehension (en inglés)
Cómo verificar antes de publicar
- Calcula la razón de cada par de tokens de texto y compárala con el umbral de su tamaño, sin redondear.
- Revisa cada anillo de foco contra las dos superficies adyacentes, dentro de la tarjeta y fuera de ella.
- Lee el control deshabilitado con el brazo estirado y decide si la etiqueta todavía dice qué acción está bloqueada.
- Confirma que ninguna sombra carga la separación sola, y que un borde o un paso de claridad la reemplaza.
- Busca en los estilos valores hexadecimales que evitan el archivo de tokens y mueve cada uno a un token.
- Cambia el tema con el chequeo corriendo y confirma que los dos temas informan valores distintos para los mismos tokens.
- Prueba el área de menor contraste de cualquier degradado o imagen detrás de texto, no el promedio.
- Corre el chequeo en el build, para que un color fijo nuevo falle antes de llegar a una persona.
Un tema oscuro que pasa el mismo chequeo que el tema claro es una segunda escala, no un filtro. Construye la escala con tokens, mídela en el build y deja que la persona elija el lado.


