Accesibilidad cromática: contraste, daltonismo y WCAG
Utilidades陈雨萱
Accesibilidad cromática: no es solo "verse bien"
Aproximadamente el 8% de los hombres y el 0.5% de las mujeres en el mundo tienen deficiencias de visión cromática: 1 de cada 12 usuarios no puede distinguir normalmente ciertos colores.
| Tipo de deficiencia cromática | Prevalencia | Colores difíciles de distinguir |
|---|---|---|
| Protanopía (ceguera al rojo) | 1% | Rojo-verde |
| Deuteranopía (ceguera al verde) | 5% | Rojo-verde |
| Tritanopía (ceguera al azul) | 0.003% | Azul-amarillo |
| Acromatopsia (ceguera total al color) | Extremadamente rara | Todos |
I. Estándares de contraste WCAG
Niveles de cumplimiento
| Nivel | Texto normal | Texto grande | Componentes UI |
|---|---|---|---|
| AA | ≥ 4.5:1 | ≥ 3:1 | ≥ 3:1 |
| AAA | ≥ 7:1 | ≥ 4.5:1 | — |
Definición de texto grande: ≥ 18pt (24px) o ≥ 14pt negrita (18.66px bold).
Cálculo del contraste
Contraste = (L1 + 0.05) / (L2 + 0.05)
L1 = Luminancia relativa del color más claro
L2 = Luminancia relativa del color más oscuro
Luminancia relativa L:
Para sRGB donde sRGB ≤ 0.03928: L = sRGB / 12.92
Para sRGB donde sRGB > 0.03928: L = ((sRGB + 0.055) / 1.055)^2.4
sRGB = R/255, G/255, B/255 (calculado por canal)
Contraste de combinaciones comunes
| Primer plano | Fondo | Contraste | AA texto normal | AA texto grande |
|---|---|---|---|---|
#000000 |
#FFFFFF |
21:1 | ✅ | ✅ |
#333333 |
#FFFFFF |
12.6:1 | ✅ | ✅ |
#666666 |
#FFFFFF |
5.7:1 | ✅ | ✅ |
#767676 |
#FFFFFF |
4.5:1 | ✅ (justo) | ✅ |
#999999 |
#FFFFFF |
2.8:1 | ❌ | ❌ |
#FF0000 |
#FFFFFF |
3.99:1 | ❌ | ✅ |
#0000FF |
#FFFFFF |
8.59:1 | ✅ | ✅ |
II. Verificación del contraste con ToolsKu
Pasos de operación
- Abre la herramienta de contraste de color
- Ingresa el color de primer plano y fondo (soporta HEX, RGB, HSL)
- Revisa los resultados:
- Ratio de contraste
- Estado de cumplimiento WCAG AA / AAA
- Evaluación separada para texto normal / texto grande
- Ajusta los colores hasta que cumplan
III. Simulación de daltonismo
Simulación con CSS filter
/* Protanopía */
.protanopia { filter: url('#protanopia'); }
/* Deuteranopía */
.deuteranopia { filter: url('#deuteranopia'); }
/* Tritanopía */
.tritanopia { filter: url('#tritanopia'); }
Matriz de filtro SVG
<svg style="display:none">
<!-- Matriz de simulación de protanopía -->
<filter id="protanopia">
<feColorMatrix type="matrix" values="
0.567 0.433 0 0 0
0.558 0.442 0 0 0
0 0.242 0.758 0 0
0 0 0 1 0
"/>
</filter>
<!-- Matriz de simulación de deuteranopía -->
<filter id="deuteranopia">
<feColorMatrix type="matrix" values="
0.625 0.375 0 0 0
0.7 0.3 0 0 0
0 0.3 0.7 0 0
0 0 0 1 0
"/>
</filter>
</svg>
IV. Estrategias de adaptación para daltonismo
Estrategia 1: No depender solo del color para transmitir información
<!-- Incorrecto: distinguir estados solo con color -->
<span class="status-error" style="color: red">Fallido</span>
<span class="status-success" style="color: green">Exitoso</span>
<!-- Correcto: color + icono -->
<span class="status-error" style="color: red">
<svg>✕</svg> Fallido
</span>
<span class="status-success" style="color: green">
<svg>✓</svg> Exitoso
</span>
Estrategia 2: Usar combinaciones de colores amigables para daltónicos
| Combinación a evitar | Combinación alternativa |
|---|---|
| Rojo + Verde | Rojo + Azul, o Naranja + Azul |
| Rojo claro + Verde claro | Rojo oscuro + Verde claro |
| Verde éxito + Rojo error | Azul información + Naranja advertencia |
Paleta amigable para daltónicos de Wong
#000000 Negro
#E69F00 Naranja
#56B4E9 Azul cielo
#009E73 Verde azulado
#F0E442 Amarillo
#0072B2 Azul
#D55E00 Rojo bermellón
#CC79A7 Rosa púrpura
Esta paleta es distinguible bajo todos los tipos de deficiencias de visión cromática.
Estrategia 3: Usar texturas/patrones en gráficos
/* Diferentes series de datos usan diferentes texturas */
.series-a { background-image: url('stripes.svg'); }
.series-b { background-image: url('dots.svg'); }
.series-c { background-image: url('crosshatch.svg'); }
V. Accesibilidad en modo oscuro
Trampas de contraste en modo oscuro
| Trampa | Descripción | Solución |
|---|---|---|
| Fondo negro puro con texto blanco puro | Contraste 21:1, pero causa fatiga visual | Usar fondo gris oscuro (#1a1a2e) |
| Reducir saturación | Alta saturación en modo oscuro es deslumbrante | Reducir saturación apropiadamente |
| Sombras no visibles | Las sombras desaparecen en fondo oscuro | Usar bordes o diferencia de luminancia |
| Contraste insuficiente de imágenes | Detalles de imágenes se pierden en modo oscuro | Ajustar con CSS filter |
Sugerencias de colores para modo oscuro
:root {
/* Modo claro */
--bg: #ffffff;
--fg: #1a1a2e;
--muted: #6b7280;
--accent: #3b82f6;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #1a1a2e;
--fg: #e0e0e0;
--muted: #9ca3af;
--accent: #60a5fa; /* Azul más claro, mantiene contraste */
}
}
VI. Verificación de accesibilidad a nivel de componente
Mensajes de error en formularios
<!-- Incorrecto: solo borde rojo como indicación -->
<input style="border: 1px solid red" />
<!-- Correcto: borde + texto + aria -->
<input
style="border: 1px solid red"
aria-invalid="true"
aria-describedby="error-msg"
/>
<span id="error-msg" role="alert" style="color: #dc2626">
Por favor ingresa una dirección de correo válida
</span>
Contraste entre enlaces y texto circundante
Los enlaces no solo necesitan suficiente contraste con el fondo, sino también distinción visual con el texto circundante:
/* Los enlaces se distinguen no solo por color, sino también por subrayado */
a {
color: var(--accent);
text-decoration: underline;
text-underline-offset: 2px;
}
VII. Detección automatizada
Integración con axe-core
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
test('accesibilidad cromática', async () => {
const { container } = render(<MyComponent />);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
Auditoría con Lighthouse
npx lighthouse https://example.com --only-categories=accessibility
Integración CI
- name: Accessibility check
run: npx pa11y https://staging.example.com
VIII. Lista de mejores prácticas
- Contraste de texto ≥ 4.5:1 (texto normal nivel AA)
- No depender solo del color para transmitir información de estado
- Usar paleta amigable para daltónicos (como la paleta de Wong)
- Agregar texturas/patrones a gráficos para distinguir
- Mantener contraste en modo oscuro, evitar fondo negro puro
- Los enlaces tienen subrayado u otra distinción no cromática
- Los mensajes de error tienen texto descriptivo, no solo color rojo
- Pruebas automatizadas de accesibilidad integradas en CI
#无障碍#WCAG#对比度#色盲#色彩设计