Cómo comprobar el contraste de color para WCAG
Comprueba las relaciones de contraste WCAG para texto, componentes UI, indicadores de foco y enlaces con las herramientas, umbrales y correcciones adecuadas.
Para comprobar el contraste de color según WCAG, compara la luminancia relativa del texto en primer plano con la de su fondo y confirma que la relación resultante cumple el umbral correspondiente a ese tipo de elemento: en el Nivel AA, eso significa 4.5:1 para texto normal, 3:1 para texto grande y 3:1 para elementos de interfaz que no son texto.
La mayoría lo aprendemos por las malas: publicamos una etiqueta gris claro que se veía bien en nuestra propia pantalla y que falló la auditoría dos sprints después. Esto no se calcula a mano: un verificador lo hace a partir de dos valores hexadecimales en segundos. Esta guía te ofrece los umbrales exactos, las formas más rápidas de medir una relación de contraste, los fallos con los que tropieza la mayoría de los equipos y las reglas que van más allá del texto del cuerpo para abarcar componentes de interfaz, indicadores de foco y significados codificados por color.
Puntos clave
- El Nivel AA de WCAG exige un contraste de 4.5:1 para texto normal y 3:1 para texto grande; el Nivel AAA eleva esas cifras a 7:1 y 4.5:1.
- Los elementos que no son texto (bordes de campos de entrada, contornos de botones, iconos con significado, segmentos de gráficos e indicadores de foco) necesitan 3:1 frente a los colores adyacentes según WCAG 1.4.11.
- El «texto grande» es aquel de 18pt (unos 24px) o de 14pt en negrita (unos 18.66px) en adelante; cualquier tamaño inferior queda sujeto al umbral de 4.5:1 propio del texto normal.
- El fallo más común es el texto del cuerpo en gris claro: #999999 sobre blanco alcanza aproximadamente 2.85:1 y no cumple, mientras que #595959 llega a 7:1 y supera tanto AA como AAA.
- WCAG 2.2 es el estándar vigente, pero sus mínimos de contraste son idénticos a los de 2.1 y 2.0. Las cifras no han cambiado.
¿Qué relación de contraste exige WCAG?
La relación de contraste mide la diferencia de luminancia entre dos colores. El mínimo es 1:1, que es lo que se obtiene cuando el primer plano y el fondo son del mismo color, y el máximo es 21:1, negro sobre blanco. WCAG la calcula como (L1 + 0.05) / (L2 + 0.05), donde L1 y L2 son la luminancia relativa del color más claro y del más oscuro. Estos son los umbrales que aplica cualquier verificador:
| Elemento | Nivel AA | Nivel AAA | Criterio de conformidad |
|---|---|---|---|
| Texto normal | 4.5:1 | 7:1 | 1.4.3 / 1.4.6 |
| Texto grande | 3:1 | 4.5:1 | 1.4.3 / 1.4.6 |
| Elementos que no son texto (interfaz, gráficos, foco) | 3:1 | — | 1.4.11 |
En el Nivel AA eso significa 4.5:1 para texto normal y 3:1 para texto grande; el Nivel AAA sube ese mismo par a 7:1 y 4.5:1. Lo que cuenta como texto grande es una cuestión de tamaño y grosor: 18pt (unos 24px) en adelante, o 14pt (unos 18.66px) en adelante si el texto está en negrita. El WebAIM Contrast Checker evalúa exactamente contra esos umbrales. Una sola regla de decisión cubre la mayoría de los casos: ¿el texto es grande? → 3:1; en caso contrario → 4.5:1.
Un mito que conviene desterrar: WCAG 2.2, publicado en octubre de 2023, añadió orientaciones sobre la apariencia del foco, pero dejó intactos los mínimos de contraste. Las versiones posteriores solo añaden criterios de conformidad en lugar de reescribir los ya existentes, con la única excepción del 4.1.1 Procesamiento (Parsing), de modo que 4.5:1 / 3:1 / 7:1 se han mantenido estables en 2.0, 2.1 y 2.2. El contraste insuficiente sigue siendo el defecto de accesibilidad más común de la web. El informe WebAIM Million de 2026 detectó texto de bajo contraste en el 83.9% del millón de páginas de inicio más visitadas.
¿Cómo se comprueba el contraste de color?
Discover how at OpenReplay.com.
El flujo de trabajo más rápido es: obtener los dos valores hexadecimales renderizados, pegarlos en un verificador y leer el resultado de aprobado/fallido. Toma el color renderizado, no el valor de tu archivo de diseño: las superposiciones, los degradados y la transparencia cambian lo que el usuario realmente ve.
- WebAIM Contrast Checker: pega los valores hexadecimales de primer plano y fondo. Obtienes la relación de contraste más cinco veredictos, ya que el texto normal y el texto grande se evalúan por separado en AA y AAA, y los elementos que no son texto tienen su propia línea de AA. Si el par no llega al umbral, los deslizadores de luminosidad (Lightness) te permiten ajustar cualquiera de los dos colores hasta que lo supere, como muestra el tutorial de WebAIM sobre la herramienta.
- TPGi Colour Contrast Analyser: una aplicación de escritorio para Windows y macOS. Selecciona cualquiera de los dos colores directamente de la pantalla con sus cuentagotas, introduce valores en hex, RGB, HSV o HSL, define un valor alfa en el primer plano y arrastra los deslizadores hasta que un par no conforme pase. También previsualiza tus colores a través de ocho configuraciones de deficiencias visuales.
- Chrome DevTools: inspecciona el elemento, abre el Color Picker desde la muestra de color junto a su declaración
colory despliega la sección Contrast ratio. Indica si el par supera AA y AAA, ofrece un botón Use suggested color que aplica un valor conforme y dibuja los límites de AA y AAA como líneas en la vista previa de tonos, de modo que puedas arrastrar el selector por debajo de ellas manualmente. - Firefox: abre DevTools → el panel Accessibility → selecciona un nodo → lee su contraste y el resultado de aprobado/fallido.
Para auditorías de páginas completas, ejecuta WAVE, axe DevTools o Lighthouse. WAVE lee los colores de texto y fondo de tus estilos y detecta la mayoría del texto del cuerpo que queda por debajo de la línea de 4.5:1 de AA, aplicando el umbral inferior de 3:1 al texto grande. Lo que no puede evaluar es el texto sobre imágenes, la composición con canal alfa o los estados hover y focus, así que verifica manualmente los componentes importantes.
Fallos de contraste comunes y cómo solucionarlos
La mayoría de los fallos se reducen a un puñado de reincidentes con soluciones rápidas y verificables.
Texto gris claro sobre blanco. #767676 sobre blanco es el gris más claro que aún supera AA con 4.5:1, mientras que #999 apenas alcanza 2.85:1 y no cumple. Oscurece el texto del cuerpo a #595959, que se sitúa exactamente en 7:1 y supera tanto AA como AAA.
/* FAIL: ~2.85:1 */ color: #999999; background: #fff;
/* PASS: 7:1 */ color: #595959; background: #fff;
Texto de marcador de posición (placeholder). Definir los placeholders con un 40–50% de opacidad es la causa habitual de un fallo del criterio 1.4.3, porque el fondo se transparenta y arrastra la relación por debajo de 4.5:1. En su lugar, asígnales un valor hexadecimal real de #767676 o más oscuro. Y utiliza una <label> persistente para todo aquello que el usuario deba leer, ya que los placeholders desaparecen al escribir.
Enlaces distinguidos solo por el color. Añade text-decoration: underline para que el enlace no se distinga únicamente por el tono. Si eliminas el subrayado, asumes un requisito adicional: el texto del enlace necesita entonces 3:1 respecto al texto del cuerpo circundante, además del 4.5:1 que ambos colores deben cumplir frente al fondo.
Texto sobre imágenes. La luminancia varía a lo largo de una fotografía, de modo que el mismo texto cumple en una zona y falla en otra. Añade una capa semitransparente (scrim):
.hero {
background:
linear-gradient(rgba(0,0,0,.6), rgba(0,0,0,.6)),
url("hero.jpg");
}
.hero-text { color: #fff; } /* now has guaranteed contrast */
Más allá del texto: componentes de interfaz, foco y uso del color
Las reglas de contraste van más allá de los párrafos. El criterio de conformidad 1.4.11 establece un mínimo de 3:1 para los controles y para las partes de un gráfico que el usuario necesita para seguir el contenido, medido frente a cualquier color que se encuentre junto a ellos. Los bordes de los campos de entrada, los contornos de los botones, los iconos que transmiten significado y las series de un gráfico entran todos en esta categoría. Los estados también cuentan, con un matiz: el estado predeterminado necesita 3:1 y ningún estado puede hacer que el componente baje de ahí, pero un efecto hover que añadas encima no está sujeto en sí mismo al 3:1, siempre que no elimine el contraste que el control ya tenía.
Los indicadores de foco son el punto donde más se confunden los números de la especificación, así que conviene ubicarlos con precisión. La visibilidad del foco corresponde a 2.4.7 Foco visible. El contraste de 3:1 del indicador proviene de 1.4.11 Contraste no textual, no del 2.4.11, que es Foco no oscurecido (mínimo) y se refiere a superposiciones que ocultan un elemento enfocado. El criterio de nivel AAA 2.4.13 Apariencia del foco añade, además, requisitos mínimos de tamaño y de contraste en el cambio de estado.
Por último, WCAG 1.4.1 Uso del color (Nivel A) significa que el color por sí solo nunca debe transmitir significado: acompaña un estado rojo/verde con una etiqueta de texto o un icono, y subraya los enlaces. Una exención que conviene recordar: los componentes inactivos (deshabilitados) quedan excluidos de los mínimos de contraste textual y no textual, pero mantenerlos legibles sigue siendo mejor experiencia de usuario que atenuarlos hasta hacerlos invisibles.
Integra el contraste en tu flujo de trabajo
Detecta los problemas de contraste antes de publicar. Compruébalo durante el diseño con un plugin como Stark dentro de Figma y, después, codifica los resultados en una capa de tokens que anote la relación de contraste de cada color:
:root {
--text-primary: #171717; /* 18.8:1 — headings, body */
--text-secondary: #595959; /* 7:1 — secondary text */
--border-input: #767676; /* 4.5:1 — meets 1.4.11 */
--border-subtle: #d4d4d4; /* 1.6:1 — decorative only */
}
El texto del cuerpo debería situarse bastante por encima del mínimo (10:1 o más resulta cómodo), mientras que el texto secundario y el texto grande pueden mantenerse en 4.5:1 y los bordes en 3:1. Prueba la percepción del daltonismo en Chrome DevTools → Rendering → Emulate vision deficiencies para confirmar que el significado se conserva sin el color. Después, automatiza: ejecuta axe o Lighthouse en CI para que una regresión de contraste rompa la compilación en lugar de llegar a los usuarios. Y dedica una revisión propia al modo oscuro: invertir la luminancia rompe relaciones de contraste que sí cumplían en el modo claro, así que recalcula cada token por tema.
El contraste es uno de los problemas de accesibilidad más baratos de solucionar y uno de los más fáciles de prevenir. Elige un verificador, define tus umbrales como tokens, integra un análisis automatizado en CI y los fallos anteriores dejarán de llegar a producción. Empieza hoy auditando el texto de tu cuerpo actual y tus estilos de foco frente a las líneas de 4.5:1 y 3:1.
Preguntas frecuentes
¿El contraste según WCAG mide el tono y la saturación, o solo la luminosidad?
La relación de contraste mide únicamente la luminancia relativa, es decir, el brillo percibido de cada color, no el tono ni la saturación. Por eso dos colores que se ven distintos, como texto rojo sobre fondo verde, pueden no cumplir si su luminancia es similar. La relación se calcula como (L1 + 0.05) / (L2 + 0.05) a partir de los valores de luminancia más claro y más oscuro, de modo que el significado transmitido únicamente mediante el tono se rige por separado en WCAG 1.4.1 Uso del color.
¿Cuál es la diferencia entre WCAG 1.4.11 Contraste no textual y 2.4.11 Foco no oscurecido?
WCAG 1.4.11 Contraste no textual (Nivel AA) exige una relación de contraste de 3:1 para los componentes de interfaz y los gráficos con significado, incluido el indicador de foco, frente a los colores adyacentes. WCAG 2.4.11 Foco no oscurecido (mínimo, Nivel AA), nuevo en WCAG 2.2, no guarda relación con el contraste: exige que un elemento enfocado no quede totalmente oculto por contenido creado por el autor, como cabeceras fijas o superposiciones. El contraste es 1.4.11; la visibilidad frente a obstrucciones es 2.4.11.
¿Por qué el mismo texto cumple el contraste en mi archivo de diseño pero falla en el navegador?
Los plugins de los archivos de diseño comprueban los valores de color planos que asignas, pero los navegadores componen el resultado renderizado. La opacidad, las superposiciones semitransparentes, los degradados, las imágenes de fondo y los modos de fusión modifican la luminancia real que ve el usuario. Un placeholder con un 50 por ciento de opacidad o un texto sobre una fotografía pueden cumplir en el mockup y fallar una vez renderizados. Toma siempre el valor hexadecimal renderizado desde DevTools o con una herramienta cuentagotas en pantalla, en lugar de confiar en el color de origen.
¿Los botones deshabilitados y los controles inactivos deben cumplir los mínimos de contraste de WCAG?
No. WCAG 1.4.3 Contraste (mínimo) exime explícitamente a los componentes de interfaz de usuario inactivos, y los elementos deshabilitados también quedan excluidos del requisito de contraste no textual 1.4.11. Eso significa que un botón deshabilitado atenuado no fallará una auditoría automatizada de contraste. Mantener legibles los controles deshabilitados sigue siendo mejor en términos de usabilidad, ya que los controles completamente invisibles confunden a los usuarios, pero no es un requisito de conformidad con WCAG para ese estado.
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data.
Star on GitHub12k