Accesibilidad (a11y)
ARIA, lectores de pantalla y diseño inclusivo
¿Qué es la Accesibilidad Web?
La accesibilidad web (a11y—"a" + 11 letras + "y") asegura que las personas con discapacidades puedan usar tu sitio web. Esto incluye:
Visual
Ceguera, baja visión, daltonismo
Auditiva
Sordera o dificultad auditiva
Motora
Movilidad limitada, usuarios solo de teclado
Cognitiva
Discapacidades de aprendizaje, problemas de memoria
La accesibilidad beneficia a todos—usuarios móviles, personas mayores, personas con lesiones temporales, usuarios bajo luz solar intensa, etc.
HTML Semántico: La Base
Usar los elementos HTML correctos proporciona accesibilidad incorporada:
Inaccesible
<div onclick="submit()">
Haz clic aquí
</div>
No accesible por teclado (sin foco con Tab)
Los lectores de pantalla no saben que es clicable
Sin soporte para tecla Enter
Accesible
<button onclick="submit()">
Haz clic aquí
</button>
Accesible por teclado (Tab + Enter)
Los lectores de pantalla anuncian "Botón: Haz clic aquí"
Funciona con tecnología asistiva
Texto Alternativo para Imágenes
Esencial para usuarios de lectores de pantalla y cuando las imágenes no cargan.
Malo
<img src="perro.jpg" />
<img src="grafico.png" alt="imagen" />
<img src="logo.svg" alt="logo.svg" />
El lector de pantalla no dice nada o información inútil
Bueno
<img src="perro.jpg" alt="Golden retriever jugando a buscar" />
<img src="grafico.png" alt="Las ventas aumentaron 45% en Q4 2024" />
<!-- Imágenes decorativas -->
<img src="divisor.png" alt="" />
Descriptivo, contextual, o vacío para decorativas
Navegación por Teclado
Muchos usuarios navegan sin ratón. Asegura que todos los elementos interactivos sean accesibles por teclado.
Controles Clave del Teclado
No accesible por teclado
<div onclick="mostrarMenu()">
Menú
</div>
<span onclick="abrirModal()">
Ver detalles
</span>
Accesible por teclado
<button onclick="mostrarMenu()">
Menú
</button>
<button onclick="abrirModal()">
Ver detalles
</button>
ARIA (Aplicaciones de Internet Ricas Accesibles)
Los atributos ARIA mejoran la accesibilidad cuando el HTML semántico no es suficiente.
Primera Regla de ARIA: ¡No uses ARIA a menos que tengas que hacerlo!
El HTML semántico es usualmente mejor. Usa ARIA solo cuando HTML solo no puede transmitir el significado.
aria-label
Proporciona nombre accesible cuando el texto visible no es suficiente:
<button aria-label="Cerrar diálogo">
x
</button>
<button aria-label="Buscar">
(icono de búsqueda)
</button>
<a href="/perfil" aria-label="Ver tu perfil">
<img src="avatar.jpg" alt="" />
</a>
aria-labelledby y aria-describedby
Vincula elementos a sus etiquetas/descripciones:
<h2 id="titulo-dialogo">Confirmar eliminación</h2>
<p id="desc-dialogo">Esta acción no se puede deshacer.</p>
<div
role="dialog"
aria-labelledby="titulo-dialogo"
aria-describedby="desc-dialogo"
>
<!-- contenido del diálogo -->
</div>
aria-hidden
Oculta elementos decorativos de los lectores de pantalla:
<button>
<span aria-hidden="true">*</span>
Favorito
</button>
<!-- Iconos decorativos -->
<span class="icon" aria-hidden="true">-></span>
role
Define el propósito del elemento cuando el HTML semántico no está disponible:
<div role="button" tabindex="0">
Botón personalizado
</div>
<div role="navigation">
<!-- enlaces de navegación -->
</div>
<div role="alert">
¡Formulario enviado con éxito!
</div>
aria-live
Anuncia cambios de contenido dinámico:
<!-- Polite: espera a que el lector termine -->
<div aria-live="polite">
3 artículos en el carrito
</div>
<!-- Assertive: interrumpe inmediatamente -->
<div aria-live="assertive" role="alert">
Error: ¡El pago falló!
</div>
Gestión del Foco
Haz visibles los estados de foco y gestiona el flujo del foco:
Malo
/* Elimina el contorno de foco */
button:focus {
outline: none;
}
Los usuarios de teclado no pueden ver dónde están
Bueno
/* Estilos de foco personalizados */
button:focus {
outline: 2px solid blue;
outline-offset: 2px;
}
/* O usa :focus-visible */
button:focus-visible {
outline: 2px solid blue;
}
Indicador visual claro para usuarios de teclado
Errores Comunes de Accesibilidad
- Usar divs/spans para botones: Usa
<button>en su lugar - Falta de texto alt: Cada imagen necesita
alt(incluso vacío para decorativas) - Contraste de color pobre: El texto debe ser legible (ratio mínimo 4.5:1)
- Sin acceso por teclado: Todos los elementos interactivos deben ser accesibles por teclado
- Eliminar contornos de foco: No uses
outline: nonesin estilos de foco personalizados - Reproducción automática de medios: No reproduzcas videos/audio automáticamente sin controles
- Inputs de formulario sin labels: Cada input necesita un
<label>
Lista de Verificación de Accesibilidad
- Usa HTML semántico:
<button>,<nav>,<main>, etc. - Proporciona texto alt: Descriptivo para imágenes significativas, vacío para decorativas
- Asegura navegación por teclado: Prueba solo con la tecla Tab
- Mantén contraste de color: Usa verificadores de contraste en línea
- Etiqueta todos los inputs: Usa
<label for="id"> - Usa ARIA con moderación: Solo cuando el HTML semántico no es suficiente
- Proporciona enlaces de salto: "Saltar al contenido principal" para usuarios de teclado
- Prueba con lectores de pantalla: NVDA (Windows), VoiceOver (Mac), JAWS
- Usa jerarquía de encabezados: h1, h2, h3 (no saltes niveles)
Herramientas de Prueba
- Lighthouse: Integrado en Chrome DevTools, audita accesibilidad
- WAVE: Extensión de navegador para evaluación visual de accesibilidad
- axe DevTools: Pruebas de accesibilidad completas
- Prueba de teclado: Navega tu sitio usando solo Tab, Enter, Espacio, teclas de flecha
- Lectores de pantalla: NVDA (gratis, Windows), VoiceOver (Mac), JAWS (Windows)
- Verificador de contraste: WebAIM Contrast Checker