Documentación de UXR SEO Analyzer

Introducción

Contraste de Color

Ver contenido

Introducción

El contraste de color es la diferencia en luminancia entre el primer plano (texto) y los colores de fondo. Un contraste suficiente asegura que el texto sea legible para personas con discapacidades visuales, daltonismo o aquellas que ven contenido en condiciones de iluminación difíciles.

El Criterio de Éxito 1.4.3 de WCAG 2.2 (Contraste Mínimo) es un requisito de Nivel AA, lo que significa que es esencial para la mayoría de estándares de cumplimiento legal. Entender e implementar el contraste apropiado es una de las mejoras de accesibilidad más impactantes que puedes hacer.

¿Qué Es el Contraste de Color?

La Relación de Contraste

La relación de contraste mide la luminancia relativa entre dos colores en una escala de 1:1 (sin contraste) a 21:1 (contraste máximo—negro sobre blanco).

Escala de Relación de Contraste:
├── 1:1   → Colores idénticos (texto invisible)
├── 3:1   → Mínimo para texto grande (AA)
├── 4.5:1 → Mínimo para texto normal (AA)
├── 7:1   → Contraste mejorado (AAA)
└── 21:1  → Máximo (negro puro sobre blanco)

Requisitos WCAG

Tipo de Texto Nivel AA Nivel AAA
Texto normal (<18pt o <14pt negrita) 4.5:1 7:1
Texto grande (≥18pt o ≥14pt negrita) 3:1 4.5:1
Componentes UI y gráficos 3:1 N/A

Texto normal = menos de 18 puntos (24px) o menos de 14 puntos (18.5px) negrita Texto grande = al menos 18 puntos (24px) o al menos 14 puntos (18.5px) negrita

Por Qué Importa el Contraste

Quién Se Beneficia

  1. Personas con baja visión - Agudeza visual reducida hace ilegible el texto de bajo contraste
  2. Adultos mayores - La sensibilidad al contraste disminuye con la edad
  3. Usuarios daltónicos - 8% de hombres y 0.5% de mujeres tienen deficiencia de visión de colores
  4. Todos - Usuarios móviles bajo luz solar, usuarios cansados, etc.

Impacto en el Negocio

Consecuencias del Bajo Contraste:
┌─────────────────────────────────────────────────────────┐
│ Usuarios no pueden leer → Abandonan tu sitio           │
│ Etiquetas de formulario poco claras → Formularios      │
│ CTAs invisibles → Conversiones perdidas                │
│ Exposición legal → Demandas de accesibilidad           │
└─────────────────────────────────────────────────────────┘

Problemas Comunes de Contraste

1. Texto Gris Claro sobre Blanco

/* MAL: relación 2.5:1 - Falla AA */
color: #999999;
background: #ffffff;

/* BIEN: relación 4.6:1 - Pasa AA */
color: #767676;
background: #ffffff;

2. Texto Placeholder

/* MAL: Placeholders predeterminados a menudo fallan */
::placeholder {
  color: #c0c0c0; /* relación 1.9:1 */
}

/* BIEN: Contraste de placeholder suficiente */
::placeholder {
  color: #757575; /* relación 4.6:1 */
}

3. Botones de Bajo Contraste

/* MAL: Azul claro sobre blanco */
.button {
  background: #87ceeb;
  color: #ffffff;
}

/* BIEN: Azul más oscuro para contraste */
.button {
  background: #0066cc;
  color: #ffffff;
}

4. Indicadores de Foco

/* MAL: Anillo de foco sutil */
:focus {
  outline: 1px solid #cccccc;
}

/* BIEN: Foco visible con contraste suficiente */
:focus {
  outline: 2px solid #005fcc;
  outline-offset: 2px;
}

Probando el Contraste

Prueba Rápida en Navegador

  1. Abrir Chrome DevTools (F12)
  2. Inspeccionar un elemento con texto
  3. Mirar el selector de color—muestra la relación de contraste
  4. Marca verde = pasa, advertencia = falla

Herramientas Online

  • WebAIM Contrast Checker: Ingresar colores de primer plano/fondo
  • Stark: Extensión de navegador con simulación de daltonismo
  • axe DevTools: Scanner automatizado de accesibilidad

Cálculo Manual

La fórmula de relación de contraste usa luminancia relativa:

Relación de Contraste = (L1 + 0.05) / (L2 + 0.05)
Donde L1 = luminancia del color más claro
      L2 = luminancia del color más oscuro

No necesitas calcular esto manualmente—usa las herramientas de arriba.

Correcciones Rápidas

Oscureciendo Colores Claros

Original Reemplazo Mejora
#999999 (2.5:1) #767676 (4.5:1) Pasa AA
#b3b3b3 (1.7:1) #595959 (7.0:1) Pasa AAA
#cccccc (1.3:1) #4d4d4d (9.0:1) Pasa AAA

Aclarando Fondos

Si no puedes oscurecer el texto, aclara el fondo:

/* Opción 1: Texto más oscuro */
color: #595959;
background: #ffffff;

/* Opción 2: Fondo con tinte */
color: #0066cc;
background: #e6f2ff;

¿Qué Pasa con los Colores de Marca?

Si tus colores de marca no cumplen requisitos de contraste:

  1. Ajustar el tono - Usar una versión más oscura/clara para texto
  2. Cambiar uso - Usar colores de marca para elementos decorativos grandes, no texto
  3. Agregar alternativas - Modo oscuro puede ayudar con ciertos esquemas de color

Implementación

Entendiendo los Requisitos de Contraste

Matriz de Contraste WCAG

Tipo de Contenido Nivel AA Nivel AAA Criterio WCAG
Texto normal 4.5:1 7:1 1.4.3 / 1.4.6
Texto grande (≥18pt/14pt negrita) 3:1 4.5:1 1.4.3 / 1.4.6
Componentes UI 3:1 N/A 1.4.11
Objetos gráficos 3:1 N/A 1.4.11
Indicadores de foco 3:1 N/A 1.4.11
Subrayados de enlaces 3:1 N/A 1.4.1

La Fórmula de Contraste

La relación de contraste se calcula usando luminancia relativa:

Relación de Contraste = (L1 + 0.05) / (L2 + 0.05)

Donde:
L1 = Luminancia relativa del color más claro
L2 = Luminancia relativa del color más oscuro

Luminancia Relativa = 0.2126 * R + 0.7152 * G + 0.0722 * B

Para cada componente RGB:
Si sRGB ≤ 0.04045: valor = sRGB / 12.92
Si sRGB > 0.04045: valor = ((sRGB + 0.055) / 1.055) ^ 2.4

Nota: Usa herramientas automatizadas en lugar de cálculo manual.

Herramientas de Testing

DevTools del Navegador

Chrome DevTools:
1. Inspeccionar elemento
2. Click en muestra de color en panel Estilos
3. Ver sección "Contrast ratio"
4. Ver estado de cumplimiento AA/AAA

Herramientas de Línea de Comandos

# Usando Pa11y para verificación de contraste
npx pa11y https://ejemplo.com --include-notices --include-warnings

# Usando axe-cli
npx @axe-core/cli https://ejemplo.com

Testing Automatizado

// Cypress con axe-core
import 'cypress-axe';

describe('Tests de Contraste', () => {
  beforeEach(() => {
    cy.visit('/');
    cy.injectAxe();
  });

  it('no debe tener violaciones de contraste', () => {
    cy.checkA11y(null, {
      rules: {
        'color-contrast': { enabled: true }
      }
    });
  });
});

Plugins de Herramientas de Diseño

Herramienta Plugin Características
Figma Stark Simulación daltonismo, verificación contraste
Figma A11y - Color Contrast Relación de contraste en tiempo real
Sketch Stark Igual que versión Figma
Adobe XD Color Contrast Analyzer Verificador de contraste integrado

Violaciones Comunes y Correcciones

Problemas de Contraste de Texto

Problema: Texto Gris Claro
/* FALLA AA - relación 2.85:1 */
.texto-atenuado {
  color: #999999;
  background-color: #ffffff;
}

/* PASA AA - relación 4.54:1 */
.texto-atenuado {
  color: #767676;
  background-color: #ffffff;
}

/* PASA AAA - relación 7.0:1 */
.texto-atenuado {
  color: #595959;
  background-color: #ffffff;
}
Problema: Texto Placeholder
/* FALLA - Placeholders predeterminados a menudo tienen bajo contraste */
input::placeholder {
  color: #c0c0c0; /* 1.9:1 */
}

/* PASA AA - Placeholder mejorado */
input::placeholder {
  color: #757575; /* 4.6:1 */
}

/* Alternativa: Usar etiquetas visibles en lugar de placeholders */
Problema: Texto Coloreado sobre Fondo Coloreado
/* FALLA - Azul sobre azul claro: 2.1:1 */
.aviso {
  color: #4a90d9;
  background-color: #e3f2fd;
}

/* PASA AA - Azul más oscuro: 4.6:1 */
.aviso {
  color: #1565c0;
  background-color: #e3f2fd;
}

Contraste de Componentes UI (WCAG 1.4.11)

Botones
/* FALLA - Borde de botón muy claro */
.btn-outline {
  border: 1px solid #cccccc; /* 1.6:1 contra blanco */
  color: #333333;
  background: transparent;
}

/* PASA - Contraste de borde suficiente */
.btn-outline {
  border: 2px solid #767676; /* 4.5:1 contra blanco */
  color: #333333;
  background: transparent;
}
Campos de Formulario
/* FALLA - Bordes de input se mezclan con fondo */
input {
  border: 1px solid #e0e0e0; /* 1.4:1 */
  background: #ffffff;
}

/* PASA - Límites de input visibles */
input {
  border: 1px solid #767676; /* 4.5:1 */
  background: #ffffff;
}

/* Alternativa: Usar diferencia de color de fondo */
input {
  border: 1px solid #e0e0e0;
  background: #f5f5f5; /* Crea límite visual */
}
Indicadores de Foco
/* FALLA - Visibilidad de foco insuficiente */
:focus {
  outline: 1px solid #cccccc;
}

/* PASA - Indicador de foco claro */
:focus {
  outline: 2px solid #005fcc;
  outline-offset: 2px;
}

/* Mejorado: Múltiples señales visuales */
:focus {
  outline: 3px solid #005fcc;
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(0, 95, 204, 0.2);
}

Enlaces

/* FALLA - Enlaces distinguidos solo por color */
a {
  color: #0066cc;
  text-decoration: none;
}

/* PASA - Indicador visual adicional */
a {
  color: #0066cc;
  text-decoration: underline;
}

/* Alternativa: Otras señales visuales */
a {
  color: #0066cc;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}

a:hover,
a:focus {
  text-decoration: underline;
}

Estrategias de Diseño

Creando Paletas de Color Accesibles

// Colores base con variantes seguras para contraste
$colors: (
  primary: (
    50: #e3f2fd,   // Fondo
    500: #2196f3,  // Solo decorativo
    700: #1565c0,  // Texto sobre blanco (4.6:1)
    900: #0d47a1   // Texto sobre blanco (8.0:1)
  ),
  gray: (
    100: #f5f5f5,  // Fondo claro
    500: #9e9e9e,  // Solo decorativo
    600: #757575,  // Texto sobre blanco (4.6:1)
    900: #212121   // Texto alto contraste
  )
);

Diseño Amigable para Daltonismo

/* No dependas solo del color */

/* MAL: Error indicado solo por color rojo */
.error {
  color: red;
}

/* BIEN: Múltiples indicadores */
.error {
  color: #c62828;
  font-weight: bold;
}
.error::before {
  content: "⚠ ";
}

/* O usa íconos */
.mensaje-error {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: #c62828;
}
.mensaje-error svg {
  flex-shrink: 0;
}

Consideraciones de Modo Oscuro

/* Modo claro */
:root {
  --text-primary: #212121;    /* 15.4:1 sobre blanco */
  --text-secondary: #757575;  /* 4.6:1 sobre blanco */
  --background: #ffffff;
  --surface: #f5f5f5;
}

/* Modo oscuro */
@media (prefers-color-scheme: dark) {
  :root {
    --text-primary: #e0e0e0;    /* 12.6:1 sobre fondo oscuro */
    --text-secondary: #9e9e9e;  /* 5.0:1 sobre fondo oscuro */
    --background: #121212;
    --surface: #1e1e1e;
  }
}

/* Aplicar consistentemente */
body {
  color: var(--text-primary);
  background-color: var(--background);
}

Degradados e Imágenes

/* Asegurar que el texto sobre degradados/imágenes permanezca legible */

/* Opción 1: Overlay */
.hero-text {
  position: relative;
  z-index: 1;
}
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 0;
}

/* Opción 2: Sombra de texto */
.hero-text {
  color: #ffffff;
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.8),
    0 0 20px rgba(0, 0, 0, 0.5);
}

/* Opción 3: Fondo detrás del texto */
.hero-text {
  background: rgba(0, 0, 0, 0.7);
  padding: 1rem 2rem;
  color: #ffffff;
}

Patrones de Implementación

Propiedades Personalizadas CSS para Tematización

:root {
  /* Sistema de colores seguro para contraste */
  --color-text: hsl(0, 0%, 13%);           /* #212121 */
  --color-text-muted: hsl(0, 0%, 46%);     /* #757575 */
  --color-background: hsl(0, 0%, 100%);    /* #ffffff */
  --color-border: hsl(0, 0%, 46%);         /* #757575 */
  --color-primary: hsl(210, 79%, 46%);     /* #1976d2 */
  --color-primary-text: hsl(210, 79%, 35%);/* Para uso en texto */
  --color-focus: hsl(210, 100%, 40%);      /* #005fcc */
}

/* Uso */
body {
  color: var(--color-text);
  background: var(--color-background);
}

.link {
  color: var(--color-primary-text);
}

.border {
  border: 1px solid var(--color-border);
}

:focus-visible {
  outline: 2px solid var(--color-focus);
}

Verificaciones CI/CD Automatizadas

# Workflow de GitHub Actions
name: Tests de Accesibilidad
on: [push, pull_request]

jobs:
  a11y:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Instalar dependencias
        run: npm ci

      - name: Build
        run: npm run build

      - name: Ejecutar Pa11y
        run: |
          npx pa11y-ci --config .pa11yci.json

# .pa11yci.json
{
  "defaults": {
    "standard": "WCAG2AA",
    "runners": ["axe"],
    "threshold": 0
  },
  "urls": [
    "http://localhost:3000/",
    "http://localhost:3000/productos",
    "http://localhost:3000/contacto"
  ]
}

Documentación del Sistema de Diseño

## Guías de Contraste de Color

### Colores de Texto

| Uso | Color | Hex | Fondo Mín | Relación |
|-----|-------|-----|-----------|----------|
| Texto primario | Gray 900 | #212121 | Blanco | 15.4:1 |
| Texto secundario | Gray 600 | #757575 | Blanco | 4.6:1 |
| Enlaces | Blue 700 | #1565c0 | Blanco | 4.6:1 |

### Hacer y No Hacer

✅ HACER:
- Usar Gray 600 (#757575) o más oscuro para texto
- Agregar subrayados a enlaces
- Probar todas las combinaciones de colores

❌ NO HACER:
- Usar colores más claros que Gray 600 para texto
- Depender solo del color para significado
- Usar texto placeholder como etiquetas

Monitoreo y Mantenimiento

Checklist de Auditoría de Contraste

## Auditoría Mensual de Contraste

- [ ] Ejecutar escaneo automatizado (axe, Pa11y)
- [ ] Verificar nuevas páginas/componentes
- [ ] Verificar contraste en modo oscuro
- [ ] Probar en dispositivos móviles reales
- [ ] Revisar colores del sistema de diseño
- [ ] Verificar embeds de terceros

Manejando Casos Especiales

/* Estados deshabilitados - exentos de requisitos de contraste */
.button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Texto decorativo - exento si es puramente estético */
.watermark {
  /* No necesita cumplir contraste si no es esencial */
}

/* Logos - exentos de requisitos de contraste */
.logo {
  /* Logos de marca no necesitan cumplir contraste */
}

Referencia Rápida

Combinaciones de Colores Seguras

Fondo Colores de Texto Seguros
#ffffff (blanco) #767676 o más oscuro (4.5:1+)
#f5f5f5 (gray 100) #616161 o más oscuro (4.5:1+)
#000000 (negro) #949494 o más claro (4.5:1+)
#1565c0 (blue 700) #ffffff (4.6:1)

Artículos Relacionados


Referencias

  1. W3C - WCAG 2.2 SC 1.4.3 Contraste (Mínimo)
  2. WebAIM - Verificador de Contraste
  3. W3C - WCAG 2.2 SC 1.4.6 Contraste (Mejorado)
  4. MDN - Contraste de Color
  5. W3C - WCAG 2.2 SC 1.4.11 Contraste No Textual
  6. WebAIM - Contraste y Accesibilidad del Color
  7. Deque - Analizador de Contraste de Color
  8. A11Y Project - Contraste de Color

Artículos relacionados

Hub de categoría

Hub

Hub de Cumplimiento WCAG 2.2

La accesibilidad web asegura que los sitios web y aplicaciones puedan ser utilizados por todos, incluyendo personas con discapacidades

En la misma categoría

Introducción

Texto alternativo para lectores de pantalla

El texto alternativo (alt text) proporciona una descripción textual de las imágenes para usuarios que no pueden verlas

Última actualización: