Developer Tools

Accesibilidad Web (a11y): Guía Práctica para Desarrolladores

Aprende los principios esenciales de accesibilidad, atributos ARIA, patrones de navegación por teclado y herramientas de prueba para que tus aplicaciones web sean utilizables por todos.

8 min de lectura

Persona usando un portátil con tecnología de asistencia

Más de 1.300 millones de personas — el 16% de la población mundial — viven con algún tipo de discapacidad. La accesibilidad web garantiza que tu sitio funcione para usuarios que dependen de lectores de pantalla, navegación por teclado, acceso por interruptor u otras tecnologías de asistencia. Más allá de la inclusión, los sitios accesibles tienen mejor posicionamiento en buscadores, funcionan mejor en dispositivos móviles y, con frecuencia, son un requisito legal.

Los cuatro principios POUR

Las Pautas de Accesibilidad para el Contenido Web (WCAG) se basan en cuatro principios fundamentales. El contenido debe ser:

  1. Perceptible — La información debe presentarse de formas que los usuarios puedan percibir (no solo de forma visual).
  2. Operable — Toda la funcionalidad debe estar disponible desde el teclado.
  3. Comprensible — El contenido y las interfaces deben ser comprensibles.
  4. Robusto — El contenido debe poder ser interpretado por tecnologías de asistencia.

WCAG 2.2 define tres niveles de conformidad:

  • A — Mínimo (imprescindible)
  • AA — Objetivo estándar para la mayoría de las organizaciones
  • AAA — Máximo (aspiracional para algunos contenidos)

La mayoría de los requisitos legales (ADA, EN 301 549, EAA) exigen conformidad AA.

Primero, HTML semántico

Lo más impactante que puedes hacer por la accesibilidad es usar el elemento HTML correcto para cada propósito. Los navegadores y los lectores de pantalla ya saben qué hacer con los elementos semánticos:

<!-- ❌ Sopa de divs — sin semántica -->
<div class="header">
  <div class="nav">
    <div class="nav-item" onclick="navigate()">Home</div>
  </div>
</div>

<!-- ✅ HTML semántico — los lectores de pantalla lo entienden -->
<header>
  <nav>
    <a href="/">Home</a>
  </nav>
</header>

Elementos semánticos clave y sus roles:

Elemento Rol
<header>, <footer> Regiones de referencia
<nav> Referencia de navegación
<main> Contenido principal (uno por página)
<aside> Contenido complementario
<h1><h6> Jerarquía de encabezados
<button> Control interactivo
<a href> Enlace de navegación
<label> Etiqueta de campo de formulario
<table> Datos tabulares

Imágenes y texto alternativo

Toda imagen significativa necesita un atributo alt que describa su contenido. Las imágenes decorativas llevan un alt="" vacío para que los lectores de pantalla las omitan:

<!-- Imagen significativa -->
<img src="chart.png" alt="Gráfico de barras que muestra un aumento del 40% en ingresos en el Q1 de 2026">

<!-- Imagen decorativa -->
<img src="divider.svg" alt="">

<!-- Botón con icono — describe la acción, no el icono -->
<button>
  <img src="trash.svg" alt="Eliminar elemento">
</button>

<!-- Evita: "imagen de" es redundante -->
<!-- ❌ --> <img src="cat.jpg" alt="Imagen de un gato">
<!-- ✅ --> <img src="cat.jpg" alt="Gato atigrado naranja sentado en un alféizar">

Contraste de color

Los usuarios con baja visión o daltonismo dependen de un contraste suficiente entre el texto y el fondo.

Requisitos WCAG AA:

  • Texto normal (< 18pt): relación de contraste mínima de 4.5:1
  • Texto grande (≥ 18pt o 14pt en negrita): relación de contraste mínima de 3:1
  • Componentes de interfaz y objetos gráficos: mínimo 3:1

No dependas únicamente del color para transmitir información:

<!-- ❌ Indicador de estado solo por color -->
<span class="text-red-500">Error</span>

<!-- ✅ Color + icono + texto -->
<span class="text-red-500 flex items-center gap-1">
  <svg aria-hidden="true"><!-- icono de error --></svg>
  Error: Dirección de correo electrónico no válida
</span>

Formularios: etiquetas, errores y descripciones

Todo control de formulario necesita una etiqueta visible y asociada:

<!-- ✅ Asociación explícita de etiqueta -->
<label for="email">Dirección de correo electrónico</label>
<input id="email" type="email" aria-describedby="email-hint email-error">
<p id="email-hint" class="text-sm text-gray-500">Nunca compartiremos tu correo.</p>
<p id="email-error" role="alert" class="text-sm text-red-600" hidden>
  Por favor, introduce una dirección de correo válida.
</p>

Patrones clave de accesibilidad en formularios:

  • Usa for/id para asociar etiquetas con campos
  • Usa aria-describedby para texto de ayuda y mensajes de error
  • Usa role="alert" o aria-live="polite" para mensajes de error dinámicos
  • Usa aria-required="true" o el atributo nativo required
  • Agrupa campos relacionados con <fieldset> y <legend>

Todos los elementos interactivos deben ser accesibles y operables con el teclado:

  • Tab — avanzar por los elementos enfocables
  • Shift+Tab — retroceder
  • Enter/Espacio — activar botones y casillas de verificación
  • Teclas de flecha — navegar dentro de componentes (menús, pestañas, controles deslizantes)
  • Escape — cerrar modales, descartar menús desplegables

Los indicadores de foco deben ser visibles. Nunca hagas esto sin una alternativa:

/* ❌ Oculta completamente el indicador de foco */
*:focus { outline: none; }

/* ✅ Estilo de foco personalizado que sigue siendo visible */
*:focus-visible {
  outline: 2px solid #3b82f6;
  outline-offset: 2px;
}

ARIA: cuándo y cómo usarlo

Los atributos ARIA (Accessible Rich Internet Applications) añaden significado semántico cuando el HTML por sí solo no es suficiente. La primera regla de ARIA: no uses ARIA si el HTML nativo puede hacer el trabajo.

<!-- Etiquetar elementos sin etiquetas visibles -->
<button aria-label="Cerrar diálogo">✕</button>

<!-- Describir el estado expandido -->
<button aria-expanded="false" aria-controls="menu">Menú</button>
<ul id="menu" hidden>...</ul>

<!-- Región en vivo para contenido dinámico -->
<div aria-live="polite" aria-atomic="true">
  <!-- Los lectores de pantalla anuncian los cambios en esta área -->
  3 resultados encontrados
</div>

<!-- Rol de referencia cuando no hay elemento semántico disponible -->
<div role="search">
  <input type="search" placeholder="Buscar...">
</div>

Gestión del foco en SPAs y modales

En las aplicaciones de página única, la navegación entre páginas no provoca un restablecimiento del foco del navegador. Cuando se carga una "página", mueve el foco a una ubicación significativa:

// Tras la navegación, enfoca el encabezado principal
document.querySelector("h1")?.focus();

Para modales:

  1. Cuando el modal se abre, mueve el foco al primer elemento enfocable dentro de él
  2. Atrapa el foco dentro del modal mientras está abierto (evita que Tab alcance el contenido detrás)
  3. Cuando el modal se cierra, devuelve el foco al elemento que lo activó

Pruebas de accesibilidad

Herramientas automatizadas (detectan ~30-40% de los problemas)

  • Extensión de navegador axe DevTools
  • Auditoría de accesibilidad Lighthouse en Chrome DevTools
  • Extensión de navegador WAVE

Pruebas manuales (necesarias para una cobertura completa)

  1. Navegación solo con teclado — desconecta el ratón y navega por todo tu sitio
  2. Pruebas con lector de pantalla — NVDA + Firefox (Windows), VoiceOver + Safari (Mac/iOS)
  3. Zoom al 200% — asegúrate de que no se pierde ni se superpone ningún contenido
  4. Simulación de daltonismo — Chrome DevTools → Rendering → Emulate vision deficiencies

Legibilidad

El lenguaje claro mejora la accesibilidad para usuarios con discapacidades cognitivas. Usa nuestra herramienta Readability Score para comprobar el nivel de lectura de tu contenido — apunta a un nivel de grado 8-10 para el público general.

Mejoras rápidas que puedes aplicar hoy

  1. Añade texto alt a todas las imágenes
  2. Asegúrate de que todos los campos de formulario tienen elementos <label> asociados
  3. Comprueba que el contraste de color cumple el ratio 4.5:1 para el texto del cuerpo
  4. Añade estilos :focus-visible y nunca elimines los contornos sin un reemplazo
  5. Usa <button> para acciones y <a href> para navegación (nunca al revés)
  6. Añade lang="es" (o el idioma correspondiente) a tu elemento <html>
  7. Usa un solo <h1> por página y mantén una jerarquía de encabezados lógica

La accesibilidad no es un complemento — es una característica de calidad. Crear productos accesibles desde el principio es mucho más económico que adaptarlos después, y hace que tus productos sean mejores para todos.