contrast-color() de CSS permite que el navegador elija texto negro o blanco según un color que cambia con frecuencia, como el fondo de un botón, reduciendo la carga de mantener pares de colores por separado
- Si se pasa un color base como en
color: contrast-color(var(--button-color));, la opción con mayor contraste se recalcula cuando cambia el color de fondo
- Actualmente, Safari Technology Preview usa el algoritmo de contraste de WCAG 2 y elige texto negro sobre un fondo
#317CFF, aunque para la percepción humana el blanco puede verse más natural
- Esta función no garantiza automáticamente la accesibilidad, y sigue siendo necesaria la validación de diseño con la paleta, el tamaño del texto, el grosor de la fuente y cosas como
prefers-contrast
- El CSS Working Group está limitando por ahora la función a la selección entre negro y blanco mientras termina la discusión sobre el algoritmo de contraste de WCAG 3; herramientas de selección de color más complejas podrían ampliarse después
La carga de gestión de color que reduce contrast-color()
- Al crear botones con distintos colores de fondo en un sitio o app web, normalmente hay que usar texto blanco si el fondo es oscuro y texto negro si es claro
- Antes había que definir juntos
--button-color y --button-text-color para mantener pares de colores, y en proyectos grandes o con varios equipos era difícil conservar siempre la combinación correcta
- Con
contrast-color(), si se pasa un color base en CSS, el navegador elige entre negro o blanco el que tenga mayor contraste
color: contrast-color(purple);
- En un botón se puede aplicar la variable del color de fondo junto con
contrast-color()
button {
background-color: var(--button-color);
color: contrast-color(var(--button-color));
}
- Con este enfoque, basta con definir un solo color de fondo y el navegador decide el color del texto
Derivar desde una sola variable incluso los colores por estado
- Si se usa también Relative Color Syntax, se puede generar el color de hover a partir del color base del botón y calcular con
contrast-color() también el color del texto para cada estado
:root {
--button-color: purple;
--hover-color: oklch(from var(--button-color) calc(l + .2) c h);
}
button {
background-color: var(--button-color);
color: contrast-color(var(--button-color));
text-box: cap alphabetic; /* vertically centers the text */
}
button:hover {
background-color: var(--hover-color);
color: contrast-color(var(--hover-color));
}
Resultados extraños producidos por el cálculo basado en WCAG 2
contrast-color() no resuelve automáticamente todos los problemas de contraste de accesibilidad
- Algunos colores de fondo pueden no lograr contraste suficiente ni con negro ni con blanco, así que sigue siendo necesaria la revisión de diseñadores, desarrolladores y testers
- A mayo de 2025, la implementación de Safari Technology Preview usa el algoritmo de WCAG 2
- En un fondo azul
#317CFF, WCAG 2 calcula una relación de contraste de 5.45:1 para texto negro
- En ese mismo fondo, el contraste con texto blanco se calcula como 3.84:1
contrast-color() elige negro porque es el número más alto
- Sin embargo, para la percepción humana, el blanco puede verse mejor en esta combinación, y el algoritmo de contraste de color de WCAG 2 ha sido criticado desde hace mucho tiempo
La discusión sobre algoritmos de contraste en APCA y WCAG 3
- Accessible Perceptual Contrast Algorithm (APCA) es uno de los candidatos que podrían incluirse en WCAG 3
- La APCA Contrast Calculator evalúa sobre un fondo
#317CFF el texto negro con Lc 38.7 y el texto blanco con Lc -70.9
- En la puntuación de APCA, un valor negativo significa que el texto es más claro que el fondo
- La magnitud del contraste se compara con 38.7 y 70.9, ignorando el signo
- En este resultado, el texto blanco tiene mayor contraste
- APCA prioriza el contraste basado en la percepción por encima de una simple proporción matemática, reflejando que las personas no perciben el contraste de forma lineal según el color y el brillo
- El estándar de CSS todavía exige usar el algoritmo actual, pero incluye una nota de que en el futuro podrían agregarse otros algoritmos de contraste
- Sigue en discusión qué algoritmo usará WCAG 3 y cómo se manejarán las licencias de los algoritmos candidatos
Condiciones que conviene revisar también en el diseño real
- Que
contrast-color() elija un color mejor no es lo mismo que garantizar contraste suficiente
- Especialmente en colores de tono medio, las diferencias entre algoritmos pueden ser mayores
- Para usuarios que quieren más contraste, se puede usar también la media query
prefers-contrast
@media (prefers-contrast: more) {
/* styling with more contrast */
}
- En el ejemplo se usa
#2DAD4E como color de fondo del botón de marca de un sitio web de vivero de árboles
- Según APCA, el contraste con texto blanco es Lc -60.4
- Que este valor sea suficiente depende del tamaño del texto y del grosor de la fuente
- APCA usa una puntuación única de Lc -108 a 106 en lugar de la proporción de WCAG 2
- El APCA Readability Criterion propone objetivos Bronze, Silver y Gold para ayudar a elegir tamaños y grosores de texto
- En el cálculo del ejemplo, la combinación de texto blanco con
#2DAD4E funciona con texto de 24px y font-weight 400 o superior, y si se usa font-weight 300 hace falta un mínimo de 41px
- Para usuarios que piden más contraste, se pueden definir colores separados para modo claro y modo oscuro
- Modo claro: verde más oscuro con texto blanco, Lc -76.1
- Modo oscuro: verde más claro con texto negro, Lc 75.2
--button-color: #2DAD4E; /* brand green background */
@media (prefers-contrast: more) {
@media (prefers-color-scheme: light) {
--button-color: #419543; /* darker green background */
}
@media (prefers-color-scheme: dark) {
--button-color: #77CA8B; /* lighter green background */
}
}
button {
background-color: var(--button-color);
color: contrast-color(var(--button-color));
font-size: 1.5rem; /* 1.5 * 16 = 24px at normal zoom */
font-weight: 500;
}
- En el entorno actual,
contrast-color() funciona con el algoritmo de WCAG 2, por lo que puede ser difícil usarlo en este sitio de ejemplo
- Aun así, puede ser útil desde ahora en proyectos donde el color de marca sea un verde más oscuro y la elección entre negro/blanco salga correctamente
contrast-color() es especialmente útil al definir colores para muchos estados u opciones, como enabled/disabled, light/dark mode o prefers-contrast
Por qué primero se limitó a la selección entre negro y blanco
- Actualmente
contrast-color() está mucho más simplificado que color-contrast(), que estaba en Safari Technology Preview 122
- El CSS Working Group decidió avanzar primero con una herramienta que solo elige negro o blanco en contraste con un color base, mientras sigue sin cerrarse la discusión sobre el algoritmo de contraste de WCAG 3
- Fijar las opciones en negro/blanco reduce la posibilidad de que los sitios web se rompan más adelante si cambia el algoritmo de WCAG 2
- En el futuro podrían aparecer herramientas más potentes, como elegir desde una lista de colores personalizada o indicar el nivel de contraste deseado
contrast-color() puede usarse no solo para el color del texto, sino también en varias propiedades que definen color, como fondo o borde
Aún no hay comentarios.