Color
Contraste que se puede medir, roles en lugar de hex sueltos, y qué hacer con el modo oscuro. Lo que exige WCAG y lo que recomiendan Apple, Google e IBM.
Cómo leer esta guía
Igual que en Animación: Citado (lo dice una fuente archivada), Verificado (cifra sacada del emisor) y Decisión Sensa (nuestra postura, discutible). Sin marca = trabajo pendiente.
Lo único que no se negocia: el contraste
Es la parte del color que tiene números y se comprueba con una herramienta, no con el ojo.
| Qué | Mínimo | Criterio |
|---|---|---|
| Texto normal | 4.5:1 | WCAG 1.4.3, nivel AA |
| Texto grande | 3:1 | WCAG 1.4.3, nivel AA |
| Componentes de interfaz y objetos gráficos | 3:1 | WCAG 1.4.11, nivel AA |
(Verificado — 1.4.3: «The visual presentation of text and images of text has a contrast ratio of at least 4.5:1»; 1.4.11: «at least 3:1 against adjacent color(s)».)
Texto grande significa 18 pt, o 14 pt si es negrita. (Verificado — «18 point text or 14 point bold text is judged to be large».) En CSS, con la equivalencia habitual de 1 pt = 1.333 px, eso es 24 px y 18.66 px. La conversión es nuestra; el umbral en puntos es de la norma.
Lo que no exige contraste (Citado — 1.4.3): texto de componentes inactivos, decoración pura, texto invisible, y logotipos.
El 1.4.11 es el que más se incumple sin darse cuenta: cubre el borde de un input, el estado de foco, el icono que comunica algo. Un placeholder gris clarito sobre blanco falla, y un borde de campo casi invisible también.
Decisión Sensa. AA es el suelo, no la meta. El texto de cuerpo lo llevamos por encima de 7:1 siempre que la marca lo permita, que es el umbral AAA. En texto secundario y deshabilitado aceptamos AA. No usamos color como único portador de información: siempre acompañado de forma, icono o texto.
Roles, no hex sueltos
(Citado — Material 3) La estructura que mejor aguanta el paso del tiempo es la de pares: cada color de fondo tiene su color de contenido encima. primary / on-primary, surface / on-surface, error / on-error, más las variantes *-container para superficies menos prominentes.
La gracia no es la nomenclatura de Google: es que el par obliga a decidir el contraste en el momento de definir el token, no cuando ya estás maquetando. Si tienes on-surface definido, no hay ocasión de poner un gris al azar sobre una tarjeta.
(Citado — Apple) «Avoid using the same color to mean different things. Use color consistently throughout your interface, especially when you use it to help communicate information like status or interactivity». El ejemplo que da es exacto: si el color de marca marca lo que es pulsable, usarlo también en texto no interactivo confunde.
Decisión Sensa. Todo color en producto entra como token semántico. Un hex literal en un componente es un error de revisión, no una cuestión de estilo. Los nombres describen función (--fg-muted, --surface-raised), no aspecto (--gris-3).
Claro y oscuro
(Citado — Apple) «Make sure all your app's colors work well in light, dark, and increased contrast contexts». Y sigue: si defines un color propio, hay que dar variante clara, oscura, y una de contraste aumentado para cada una. Apple añade que conviene definir ambas incluso si la app se publica en un solo modo, para que Liquid Glass se adapte.
Dos cosas que se olvidan siempre:
- El contraste no se conserva al invertir. Un par que da 5:1 en claro puede dar 3.2:1 al pasarlo a oscuro. Hay que medir los dos.
- (Citado — Apple) Las condiciones de luz cambian la percepción: «In bright surroundings, colors look darker and more muted. In dark environments, colors appear bright and saturated». Un gris que se lee en el escritorio desaparece al sol.
(Citado — Apple) En modo oscuro, saturaciones altas cansan más. Apple lo aborda por la vía de recomendar colores de sistema, que ya traen las variantes resueltas.
Anti-patrones
- Color como única señal de estado (error sólo en rojo, éxito sólo en verde).
- Placeholders y texto deshabilitado por debajo de 4.5:1 «porque tienen que verse apagados». Apagado no es ilegible; baja la jerarquía con tamaño o peso.
- Bordes de input a 1.5:1: incumple 1.4.11 aunque el texto de dentro esté perfecto.
- Invertir la paleta para el modo oscuro y no volver a medir.
- Hex literales dentro de componentes.
- Verde y rojo como único par para bien/mal.
Checklist de revisión
- ¿Todo el texto pasa 4.5:1, o 3:1 si es grande de verdad (18 pt / 14 pt negrita)?
- ¿Bordes, iconos y estados de foco pasan 3:1?
- ¿Medido en claro y en oscuro?
- ¿Alguna información depende sólo del color?
- ¿Cada color nuevo entra como token con su par de contenido?
- ¿El color de interactividad se usa sólo para lo interactivo?
- ¿Se ha mirado a plena luz?
Lo que falta
- APCA, el modelo de contraste que se plantea para WCAG 3, no está archivado y por eso aquí no hay cifras suyas. Importa porque corrige un defecto real del ratio de WCAG 2 con texto claro sobre oscuro.
- Ninguna cifra sobre prevalencia de daltonismo hasta tener fuente archivada.
- Falta decidir y documentar la paleta concreta de Sensa. Esta guía es el criterio; los valores todavía no están aquí.