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

  1. Abre la herramienta de contraste de color
  2. Ingresa el color de primer plano y fondo (soporta HEX, RGB, HSL)
  3. Revisa los resultados:
    • Ratio de contraste
    • Estado de cumplimiento WCAG AA / AAA
    • Evaluación separada para texto normal / texto grande
  4. 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

  1. Contraste de texto ≥ 4.5:1 (texto normal nivel AA)
  2. No depender solo del color para transmitir información de estado
  3. Usar paleta amigable para daltónicos (como la paleta de Wong)
  4. Agregar texturas/patrones a gráficos para distinguir
  5. Mantener contraste en modo oscuro, evitar fondo negro puro
  6. Los enlaces tienen subrayado u otra distinción no cromática
  7. Los mensajes de error tienen texto descriptivo, no solo color rojo
  8. Pruebas automatizadas de accesibilidad integradas en CI
#无障碍#WCAG#对比度#色盲#色彩设计