Contraste de color en el diseño web: cómo probar y corregir fallos de contraste

Las fallas de contraste de color son la infracción de accesibilidad más común en la web y afectan a la mayoría de los sitios web. Esta guía desglosa exactamente lo que exige WCAG, cómo encontrar fallas de contraste con las herramientas adecuadas y cómo corregirlas en tu CSS, sin sacrificar la identidad visual de tu marca.

Imagina a una persona con baja visión que llega a tu sitio web, sentada en una cafetería inundada de sol con el brillo de su teléfono al máximo. Si tu texto de cuerpo en gris claro está sobre un fondo blanco, simplemente no puede leer tu contenido, por muy cuidadosamente que hayas elaborado cada palabra. Ese escenario no es hipotético: se detectó texto con bajo contraste en el 83.9% de las principales un millón de páginas de inicio a principios de 2026, lo que lo convierte en el fallo de accesibilidad más comúnmente identificado en la web por séptimo año consecutivo, con cada página de inicio infractora promediando 34 instancias distintas del problema.

Por qué el contraste de color importa más de lo que crees

La mayoría de la gente asume que los problemas de contraste solo afectan a las personas que son totalmente ciegas o que usan lectores de pantalla. La realidad es mucho más amplia. Hay aproximadamente 300 millones de personas en todo el mundo con algún tipo de deficiencia en la visión del color, y muchas más que experimentan el bajo contraste como un punto de fricción diario: personas que usan monitores baratos, quienes tienen la vista envejecida o cualquiera que se desplace por la pantalla al aire libre en un día soleado. La baja visión es mucho más común que la ceguera total: casi tres veces más personas tienen baja visión que ausencia total de visión.

La investigación detrás de los umbrales de contraste de WCAG hace que esto sea concreto. La proporción mínima de 4.5:1 para texto estándar se calibró para compensar la pérdida de sensibilidad al contraste que suele experimentar alguien con una visión equivalente a aproximadamente 20/40, la agudeza visual que se reporta comúnmente en personas de unos ochenta años. El umbral más estricto de 7:1 del Nivel AAA de WCAG se calibró de forma similar: se dirige a personas con visión equivalente a 20/80, compensando la pérdida de sensibilidad al contraste en personas con baja visión que no usan tecnologías de asistencia.

También hay consecuencias legales y comerciales muy reales. Las demandas por accesibilidad en Estados Unidos alcanzaron 4,605 casos de accesibilidad digital bajo la ADA en 2024, y la European Accessibility Act entró en vigor en junio de 2025, extendiendo las obligaciones de cumplimiento obligatorio a una amplia gama de sitios web y aplicaciones comerciales. Los fallos de contraste de color son detectables, documentados y citados de forma habitual en litigios. Para los responsables de cumplimiento, eso convierte su corrección en una prioridad, no en algo deseable pero opcional.

Por último, un contraste accesible es simplemente buen diseño. El texto con alto contraste es más fácil de escanear para todo el mundo, reduce la carga cognitiva y mejora la velocidad de lectura en general, lo que lo convierte tanto en una mejora del rendimiento del negocio como en una obligación de cumplimiento.

Las reglas de contraste de WCAG que realmente necesitas conocer

WCAG 2 define el contraste como una medida de la diferencia en la luminancia percibida entre dos colores. La fórmula compara el brillo relativo de un color de primer plano frente a su fondo y expresa el resultado como una proporción que va de 1:1 (sin diferencia — blanco sobre blanco) a 21:1 (diferencia máxima — negro sobre blanco). No necesitas calcular esto manualmente; la clave es entender qué proporciones se requieren y cuándo se aplican.

Bajo WCAG 2.x Nivel AA, el nivel al que hacen referencia la mayoría de las leyes y normas de accesibilidad, los requisitos se desglosan de la siguiente manera:

  • Texto normal (cuerpo, etiquetas, texto de la interfaz de usuario por debajo de 18pt o 14pt en negrita): proporción de contraste mínima de 4.5:1 con respecto al fondo.
  • Texto grande (al menos 18pt / 24px, o 14pt / ~18.66px en negrita): proporción de contraste mínima de 3:1. La lógica es que las formas de las letras más grandes son intrínsecamente más fáciles de distinguir, por lo que se justifica un umbral más relajado.
  • Componentes de interfaz de usuario que no son texto y gráficos informativos (Criterio de Conformidad 1.4.11, introducido en WCAG 2.1): proporción de contraste mínima de 3:1 con respecto a los colores adyacentes. Esto cubre elementos como bordes de campos de formulario, indicadores de foco, botones solo con iconos y partes de gráficos necesarias para entender los datos.

Bajo el Nivel AAA, el listón es más alto: 7:1 para texto normal y 4.5:1 para texto grande. Aunque el Nivel AAA rara vez se exige en su totalidad, vale la pena tratarlo como objetivo de diseño para páginas o interfaces de usuario con mucho texto en las que la precisión de lectura sea crítica.

Matiz importante: WCAG define el "texto grande" por el tamaño renderizado en el navegador, no por el valor en tu CSS. Una fuente establecida en 1.2rem puede o no calificar como texto grande dependiendo del tamaño base de fuente del navegador de la persona usuaria. En caso de duda, aplica el umbral de 4.5:1 y usa herramientas para verificar el tamaño realmente renderizado.

Un pequeño conjunto de elementos está explícitamente exento de los requisitos de contraste. Las imágenes puramente decorativas, los controles de formulario deshabilitados, los logotipos y las fotografías reales no están sujetos al criterio de éxito 1.4.3. Esta excepción es sensata — no se debería obligar a un fondo de marca de agua o a una foto de producto a cumplir el mismo umbral que una etiqueta de navegación — pero los equipos suelen aplicarla mal para justificar decisiones de diseño perezosas. Si una imagen o un gráfico es necesario para entender el contenido de la página, aún debe cumplir el requisito de contraste de 3:1 para elementos que no son texto.

Otra regla importante merece atención: WCAG 1.4.1 (Uso del color). Si distingues los enlaces del texto de cuerpo circundante usando solo el color — sin subrayado, sin diferencia de grosor, sin otra pista visual — esos enlaces deben alcanzar una proporción de contraste de 3:1 con respecto al texto de cuerpo adyacente, además de cumplir la proporción estándar de 4.5:1 entre texto y fondo. Cumplir los tres requisitos simultáneamente es realmente complicado; la solución más simple es mantener los subrayados de tus enlaces.

Cómo probar los fallos de contraste

Probar el contraste es una de las partes más amigables con las herramientas dentro del trabajo de accesibilidad. El cálculo subyacente es matemático y determinista, lo que significa que las herramientas automatizadas pueden detectarlo de forma fiable, a diferencia de muchos otros problemas de accesibilidad que requieren juicio humano. Dicho esto, hay casos límite en los que la automatización se queda corta, y entender toda la pila de pruebas hará que tus auditorías sean mucho más exhaustivas.

Paso 1: Ejecuta un escaneo automatizado de la página

WAVE (la herramienta de evaluación de accesibilidad web de WebAIM) y axe DevTools son los dos escáneres basados en navegador más utilizados. Ambos están disponibles como extensiones para Chrome y Firefox. Escanean el DOM renderizado — es decir, evalúan los colores tal como el navegador realmente los pinta, después de aplicar CSS y JavaScript — y marcan los elementos de texto que no cumplen el umbral de contraste AA de WCAG. Axe DevTools va más allá al informar la gravedad de cada problema, vincularlo con el criterio de éxito de WCAG correspondiente y proporcionar orientación sobre la corrección. Para equipos empresariales, axe-core puede integrarse directamente en las canalizaciones de CI/CD para que las regresiones de contraste se detecten antes del despliegue.

Google Lighthouse, integrado en Chrome DevTools, también realiza comprobaciones de contraste como parte de su auditoría de accesibilidad. Es una primera pasada conveniente — especialmente útil porque ya forma parte del flujo de trabajo de la mayoría de desarrolladores — pero se ejecuta sobre un subconjunto de las reglas de axe-core, por lo que no es tan exhaustivo como la extensión completa de axe DevTools.

Una limitación importante: los escáneres automatizados no pueden evaluar de forma fiable el contraste de texto que se encuentra sobre un fondo con degradado, una imagen de fondo, una capa semitransparente o un elemento con apilamiento CSS complejo. Estos casos requieren inspección manual.

Paso 2: Usa el selector de color de Chrome DevTools para inspecciones puntuales

En Chrome DevTools, al abrir el panel Styles de cualquier elemento y hacer clic en la muestra de color junto a un valor de color se lanza un selector de color integrado que muestra la proporción de contraste actual con respecto al fondo calculado del elemento. Cuando el color no cumple, DevTools ofrece una función de autocorrección: muestra los colores más cercanos que cumplen AA y AAA para que puedas adoptar un valor conforme con un solo clic. Esto es muy valioso para iterar rápidamente durante el desarrollo. DevTools también incluye un emulador de deficiencias de visión en el panel Rendering, que te permite simular visión borrosa, protanopía, deuteranopía, acromatopsia y otras condiciones para obtener una sensación cualitativa de cómo las personas con alteraciones en la percepción del color experimentan tu paleta.

Paso 3: Prueba pares de colores específicos con un verificador dedicado

Para validar combinaciones de colores individuales de forma aislada — por ejemplo, durante una revisión de diseño en Figma antes de construir nada — el WebAIM Contrast Checker (webaim.org/resources/contrastchecker) es el estándar del sector. Introduces valores hexadecimales para el primer plano y el fondo, y devuelve al instante la proporción de contraste y una calificación de aprobado/suspenso para AA y AAA tanto en tamaños de texto normal como grande. La aplicación de escritorio Colour Contrast Analyser (CCA) para Windows y macOS es igual de útil y maneja casos complejos como primeros planos semitransparentes y muestreo con cuentagotas en pantalla desde cualquier aplicación, no solo el navegador.

Paso 4: Prueba en contexto: modo oscuro, estados hover e indicadores de foco

Aquí es donde muchos equipos fallan. Un par de colores que cumple en tu tema claro predeterminado puede fallar por completo en modo oscuro. Los colores de acento de marca que se ven vivos sobre un fondo blanco a menudo se vuelven apagados o deslumbrantes sobre una superficie oscura. Cada estado interactivo — hover, foco, activo, visitado — es una fuente potencial de nuevos fallos de contraste. Del mismo modo, los indicadores de foco (el contorno visible que aparece cuando una persona que usa teclado se desplaza con la tecla Tab hasta un control) deben alcanzar una proporción de contraste de 3:1 con respecto a los colores adyacentes según el Criterio de Conformidad 1.4.11 de WCAG 2.1. Prueba siempre ambos temas antes de la publicación; el modo oscuro no es automáticamente accesible solo porque se vea pulido.

Los fallos de contraste más comunes — y cómo solucionarlos

Entender los patrones de fallo que aparecen con más frecuencia en las auditorías te permite priorizar tu trabajo de corrección. La mayoría de los problemas de contraste encajan en un conjunto predecible de categorías.

Texto de cuerpo gris sobre blanco

Los grises medios como #767676 o #999999 sobre un fondo blanco son omnipresentes en el diseño plano moderno. Se sienten ligeros y refinados para diseñadores con monitores calibrados. A menudo no cumplen el umbral de 4.5:1 y son invisibles para personas con baja visión. La solución suele ser un simple cambio de valor de color: cambiar #767676 (que apenas aprueba con 4.54:1) a #595959 te da una proporción de 7.0:1 y una legibilidad sustancialmente mejor, con una diferencia visible mínima para la mayoría de las personas con visión normal.

Al trabajar en HSL — un modelo de color más intuitivo para hacer ajustes de contraste — solo necesitas modificar el componente de Luminosidad para cambiar la proporción de contraste manteniendo intactos el tono y la saturación elegidos. Sobre un fondo blanco, disminuir el valor de Luminosidad oscurece el texto y mejora el contraste; sobre un fondo oscuro, aumentarlo aclara el texto. Pequeños cambios en la Luminosidad (2–5 puntos porcentuales) suelen ser suficientes para pasar de un suspenso a un aprobado claro en AA sin cambiar perceptiblemente tu diseño.

/* Antes: no cumple WCAG AA (proporción ~3.9:1 sobre blanco) */
.body-text {
  color: #888888;
}

/* Después: cumple WCAG AA y AAA (proporción ~7.0:1) */
.body-text {
  color: #595959;
}

Texto de marcador de posición en campos de formulario

El texto de marcador de posición renderizado con el estilo predeterminado del navegador — normalmente un gris claro alrededor de #AAAAAA o #BBBBBB — casi siempre incumple WCAG AA sobre un fondo blanco de campo de entrada. Muchas personas diseñadoras mantienen intencionadamente bajo el contraste del marcador de posición para distinguirlo visualmente del contenido introducido por la persona usuaria, pero esta no es una exención permitida. El texto de marcador de posición es texto de interfaz de usuario y debe cumplir el estándar de 4.5:1. Usa un tono más oscuro y confía en el estilo en cursiva, la posición o la animación para crear la distinción visual en lugar de la luminosidad.

::placeholder {
  /* No cumple: #AAAAAA es aproximadamente 2.3:1 sobre blanco */
  color: #AAAAAA;
}

::placeholder {
  /* Cumple: #767676 es aproximadamente 4.54:1 sobre blanco */
  color: #767676;
  font-style: italic; /* Pista visual alternativa */
}

Texto blanco o claro sobre un color de marca de tono medio

Los colores de marca en el rango de saturación media — azules, verdes y morados comunes en el rango de luminosidad 5–6 de HSL — a menudo no proporcionan suficiente contraste para el texto blanco superpuesto. Un azul de marca vivo que se ve genial en un logotipo podría producir solo una proporción de 2.8:1 frente al blanco, muy por debajo del mínimo de 4.5:1 para texto de cuerpo. La solución es oscurecer el color de fondo (desplazar el tono de marca hacia un token 800 o 900 en tu sistema de diseño), cambiar a texto oscuro sobre ese fondo o reservar el color de tono medio para elementos puramente decorativos donde las reglas de contraste no se aplican.

Texto sobre imágenes de fondo o degradados

El texto colocado directamente sobre una fotografía o un degradado es uno de los casos más complicados porque la luminancia del fondo no es uniforme: la proporción de contraste cambia en distintas partes de la imagen. La solución más fiable es una superposición semitransparente oscura o clara usando CSS, aplicada como pseudo-elemento para que la imagen siga siendo visible debajo. Una superposición negra con una opacidad de alrededor del 50–60% suele llevar el texto blanco de un contraste marginal a un AAA sólido.

.hero {
  position: relative;
}

.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
}

.hero__text {
  position: relative;
  z-index: 1;
  color: #ffffff;
}

Elementos de interfaz de usuario en estado deshabilitado y secundarios

WCAG exime explícitamente a los componentes de interfaz de usuario deshabilitados de los requisitos de contraste: un botón inactivo no necesita cumplir 4.5:1. Sin embargo, muchos equipos aplican en exceso esta exención a texto secundario, pies de foto, texto de ayuda y etiquetas que en realidad no están deshabilitados. Si un elemento transmite información que la persona usuaria necesita para entender o actuar, debe cumplir el estándar de contraste aplicable independientemente de su jerarquía visual. Revisa cada tono en la escala neutra de tu sistema de diseño frente a los fondos en los que aparece.

Integrar el contraste en tu sistema de diseño

Corregir fallos de contraste individuales de forma reactiva es lento y propenso a errores. El enfoque más duradero es incorporar el cumplimiento del contraste en tu sistema de diseño para que los pares de colores accesibles se conviertan en la salida predeterminada, no en una idea tardía.

La base es una escala de tokens correctamente graduada. Cada color de tu paleta debe tener documentadas las proporciones de contraste precalculadas frente a tus colores de fondo estándar. Una convención sensata es etiquetar los tokens por su rendimiento de contraste: un token --color-text-primary debería aprobar siempre AA sobre --color-surface-default, y esa garantía debería estar documentada, probada y aplicada. Cuando una persona diseñadora recurre a un token para colorear texto, debería poder confiar en que cumple el estándar mínimo sin tener que hacer una comprobación manual cada vez.

Las propiedades personalizadas de CSS hacen que esto sea especialmente abordable. Puedes definir toda tu paleta como variables y usar media queries para intercambiarlas en modo oscuro sin codificar en duro ningún par de colores, manteniendo la gestión del cumplimiento de contraste en un solo lugar.

:root {
  --color-surface-default: #ffffff;
  --color-text-primary: #1a1a1a;   /* ~16:1 sobre blanco */
  --color-text-secondary: #595959; /* ~7.0:1 sobre blanco */
  --color-text-subtle: #767676;    /* ~4.54:1 sobre blanco */
  --color-accent: #0052cc;         /* ~8.0:1 sobre blanco */
}

@media (prefers-color-scheme: dark) {
  :root {
    --color-surface-default: #121212;
    --color-text-primary: #ededed;   /* ~14.5:1 sobre #121212 */
    --color-text-secondary: #c0c0c0; /* ~9.4:1 sobre #121212 */
    --color-text-subtle: #909090;    /* ~5.1:1 sobre #121212 */
    --color-accent: #6fa8ff;         /* ~6.5:1 sobre #121212 */
  }
}

Observa los valores de tokens de modo oscuro anteriores. Los colores que cumplen AA sobre un fondo blanco a menudo fallan sobre superficies oscuras, y viceversa. Al diseñar para modo oscuro, evita simplemente invertir tus valores de modo claro. El texto totalmente saturado o blanco puro sobre negro puro (#000000) puede causar halación, un efecto de desenfoque visual en extremos de alto contraste que resulta difícil para algunas personas. Una superficie de #121212 y texto de #ededed es una combinación más cómoda que aún logra un contraste excelente.

Las pruebas automatizadas de contraste también pueden integrarse en tu canalización de componentes. Bibliotecas como axe-core pueden invocarse en pruebas de Jest o Playwright para marcar fallos de contraste como parte de tu batería de pruebas estándar, detectando regresiones en el momento en que se introducen en lugar de en el punto de una auditoría externa.

Lo que las herramientas automatizadas no pueden detectar — y qué hacer al respecto

El escaneo automatizado es un punto de partida potente, pero tiene límites reales. Las pruebas automatizadas suelen poder detectar entre el 20 y el 30 por ciento de las posibles violaciones de WCAG si se considera toda la gama de criterios de accesibilidad, aunque el contraste de color es una de las categorías más detectables de forma fiable. Aun así, varios escenarios de fallos de contraste se escapan rutinariamente de las herramientas automatizadas.

Texto sobre degradados e imágenes de fondo es el punto ciego más común. Axe y WAVE pueden identificar pares de colores cuando tanto el primer plano como el fondo tienen un único valor de color determinista. Cuando el fondo es un degradado CSS o una fotografía JPEG, la herramienta a menudo no puede calcular una proporción significativa y marcará el elemento como "requiere revisión" en lugar de un suspenso definitivo. Estos casos requieren inspección humana, idealmente usando una herramienta de cuentagotas a nivel de píxel como Colour Contrast Analyser para muestrear los valores reales de primer plano y fondo en varios puntos de la zona de solapamiento.

Colores semitransparentes y compuestos crean desafíos similares. La proporción de contraste de una etiqueta de botón blanca sobre un botón azul renderizado sobre un fondo de página verde depende de las tres capas de color, un cálculo que las herramientas basadas en el DOM no siempre pueden realizar con precisión. Aplana manualmente los valores alfa o usa una herramienta basada en captura de pantalla para muestrear el color de píxel renderizado.

Estados generados dinámicamente — tooltips impulsados por JavaScript, cuadros de diálogo modales, menús desplegables, mensajes de error — se renderizan sobre la marcha y pueden no ser visibles cuando se ejecuta un escaneo automatizado. Las herramientas que pueden ser programadas (como axe-core en una prueba de Playwright) pueden navegar hasta estos estados y evaluarlos, pero configurar esa cobertura requiere un esfuerzo deliberado. Incorpóralo a tu flujo de trabajo de QA e incluye el contraste en tu definición de "terminado" para cada componente nuevo que introduzca nuevas combinaciones de colores.

Por último, la fórmula matemática de contraste de WCAG, aunque bien establecida, no es un sustituto perfecto de la legibilidad percibida. La fórmula no tiene en cuenta el grosor de la fuente, el espaciado entre letras ni el antialiasing. Una tipografía de grosor fino a 4.5:1 se sentirá más difícil de leer que la misma proporción lograda con un grosor mayor. Trata el umbral de WCAG como un suelo — el mínimo que debes alcanzar — en lugar de un objetivo de optimización. Apunta a 7:1 siempre que sea posible y realiza pruebas con personas que realmente tengan baja visión para validar que tus elecciones de color funcionan en el mundo real.

Conclusiones clave

  • El contraste de color es el fallo de accesibilidad número uno en la web. El texto con bajo contraste apareció en el 83.9% de las principales un millón de páginas de inicio en 2026. Independientemente de lo maduro que sea el programa de accesibilidad de tu organización, el contraste es el lugar donde es más probable que tengas fallos sin resolver ahora mismo, y está entre los más fáciles de corregir.
  • Conoce los umbrales que se aplican a tu contenido. WCAG AA exige 4.5:1 para texto normal, 3:1 para texto grande (18pt+ o 14pt+ en negrita) y 3:1 para componentes de interfaz de usuario que no son texto, como bordes de campos de entrada y controles solo con iconos. Estos se aplican tanto si tu interfaz usa modo claro como modo oscuro.
  • Prueba por capas: escaneo automatizado, inspección con DevTools, verificador independiente y revisión manual. Ejecuta axe DevTools o WAVE para un escaneo rápido de página completa; usa el selector de color integrado de Chrome DevTools para iterar rápidamente; usa WebAIM Contrast Checker o CCA para validar pares específicos; e inspecciona manualmente degradados, imágenes y estados dinámicos que las herramientas automatizadas no pueden evaluar de forma fiable.
  • Corrige el contraste a nivel de sistema de diseño, no a nivel de componente. Construye una escala de tokens con proporciones de contraste prevalidadas, documenta qué tokens de texto aprueban sobre qué tokens de superficie y aplica el cumplimiento mediante pruebas automatizadas en CI. Esto elimina clases enteras de fallos antes de que lleguen a producción.
  • Trata WCAG como un suelo, no como un objetivo. Alcanzar 4.54:1 apenas aprueba, pero aún deja a muchas personas con dificultades. Cuando la tipografía, la legibilidad y la marca lo permitan, apunta a 7:1 y usa el grosor, el tamaño y el espaciado de la fuente como palancas adicionales para que el texto sea realmente cómodo de leer, no solo técnicamente conforme.