Accesibilidad web: lo mínimo que todo frontend debería saber

Close-up view of colorful programming code on a screen, ideal for tech and development themes.
Foto de Leonid Altman en Pexels

La accesibilidad ya no es una opción, es una obligación legal y ética. Como frontend, puedes lograr que tu sitio sea usable por la mayor parte de la población sin escribir código complejo. En este artículo repasamos los conceptos esenciales que deberías aplicar en cada proyecto.

1. Usa la semántica HTML adecuada

El primer paso es confiar en las etiquetas nativas. Un <button> ya es focoable y anuncia su rol a los lectores de pantalla. Evita <div> o <span> para interacciones y, si lo haces, añade los atributos necesarios (role, tabindex, etc.).

2. Imágenes con texto alternativo

Todo <img> debe llevar alt. Si la imagen es decorativa, usa alt="" para que los lectores la ignoren. En imágenes que transmiten información, el texto alternativo debe ser conciso y descriptivo.

3. Contraste de colores

El contraste entre texto y fondo debe ser de al menos 4.5:1 para texto normal y 3:1 para texto grande. Herramientas como WebAIM Contrast Checker te facilitan la comprobación.

4. Navegación con teclado

Todos los elementos interactivos deben ser accesibles sin ratón. Usa tabindex="0" sólo cuando sea necesario y evita tabular a elementos invisibles. Un buen patrón es cerrar modales con Esc y devolver el foco al elemento que los abrió.

5. Roles y atributos ARIA

ARIA no es un sustituto de la semántica, sino un complemento. Utilízalo cuando no exista un elemento nativo que describa la función. Algunos casos típicos:

  • role="alert" para mensajes urgentes.
  • aria-live="polite" para actualizaciones dinámicas que no interrumpen.
  • aria-expanded en botones que despliegan contenido.

6. Formularios accesibles

Asocia cada <input> con su <label> usando el atributo for. Los mensajes de error deben estar vinculados mediante aria-describedby y anunciados al lector de pantalla.

7. Ejemplo práctico: botón accesible

A continuación, un componente simple que muestra cómo combinar semántica, foco y ARIA para crear un botón que abre un menú.

<button id="menuBtn" aria-haspopup="true" aria-controls="menu" aria-expanded="false">Opciones</button>
<ul id="menu" role="menu" hidden>
  <li role="menuitem" tabindex="-1">Perfil</li>
  <li role="menuitem" tabindex="-1">Configuración</li>
  <li role="menuitem" tabindex="-1">Cerrar sesión</li>
</ul>

<script>
  const btn = document.getElementById('menuBtn');
  const menu = document.getElementById('menu');
  btn.addEventListener('click', () => {
    const expanded = btn.getAttribute('aria-expanded') === 'true';
    btn.setAttribute('aria-expanded', !expanded);
    menu.hidden = expanded;
    // Cuando abrimos, movemos el foco al primer ítem
    if (!expanded) {
      const firstItem = menu.querySelector('[role="menuitem"]');
      firstItem.setAttribute('tabindex', '0');
      firstItem.focus();
    }
  });
  // Cerrar con Escape y volver al botón
  document.addEventListener('keydown', e => {
    if (e.key === 'Escape' && !menu.hidden) {
      menu.hidden = true;
      btn.setAttribute('aria-expanded', 'false');
      btn.focus();
    }
  });
</script>

Observa cómo:

  • El button indica que abre un menú (aria-haspopup).
  • Se controla el estado abierto/cerrado con aria-expanded.
  • Los ítems del menú usan role="menuitem" y reciben foco sólo cuando el menú está visible.

8. Testing y auditoría

Incluye pruebas de accesibilidad en tu flujo CI. Herramientas como axe-core o npm run test:accessibility detectan problemas comunes. Además, revisa manualmente con lectores de pantalla (NVDA, VoiceOver) y prueba la navegación con Tab y Shift+Tab.

9. Checklist rápido

  • ¿Todas las imágenes tienen alt adecuado?
  • ¿Los colores cumplen el contraste mínimo?
  • ¿Todo elemento interactivo es focoable y operable con teclado?
  • ¿Se usan roles/ARIA sólo cuando es necesario?
  • ¿Los formularios tienen label y mensajes de error accesibles?

Aplicando estos puntos básicos, tu proyecto ganará en usabilidad, SEO y cumplimiento normativo. La accesibilidad no es una capa extra, es parte del núcleo del desarrollo frontend.