Accesibilidad en React: Más allá del aria-label
En este artículo
Poner aria-label en todo no hace una interfaz accesible. En proyectos con compliance, lo que más ayuda es HTML semántico, navegación por teclado y feedback claro para lectores de pantalla.
Trabajé con dashboards LGPD, e-commerce y portales enterprise. Estas prácticas impactan a quien usa lector de pantalla o solo teclado.
1. HTML semántico antes de ARIA
La regla de WAI-ARIA sigue vigente: si existe elemento nativo, úsalo.
tsx// ❌ div disfrazado de botón
<div role="button" tabIndex={0} onClick={handleClick}>Guardar</div>
// ✅ botón real
<button type="button" onClick={handleClick}>Guardar</button>
Usa <nav>, <main>, <article>, <button> y headings en orden (h1 → h2). Los lectores navegan por landmarks — div genérica rompe ese flujo.
2. Foco visible y orden de tabulación
Cada elemento interactivo necesita :focus-visible claro. No quites el outline sin alternativa:
cssbutton:focus-visible {
outline: 3px solid rgba(124, 58, 237, 0.55);
outline-offset: 4px;
}
En modales y menús, atrapa el foco dentro del panel y devuélvelo al botón que abrió al cerrar. Prueba solo con Tab y Shift+Tab.
3. Acordeones y paneles expandibles
Para FAQ, filtros y menús, el patrón correcto es:
aria-expandeden el botón que abrearia-controlsapuntando al id del panelrole="region"en el contenido conaria-labelledby
tsx<button
aria-expanded={isOpen}
aria-controls="faq-panel-1"
id="faq-trigger-1"
>
Pregunta
</button>
<div id="faq-panel-1" role="region" aria-labelledby="faq-trigger-1">
Respuesta
</div>
Evita display: none sin pensar en el anuncio — el contenido debe ser accesible cuando está abierto.
4. Live regions para cambios dinámicos
Búsqueda, filtros y toasts deben anunciar lo que cambió:
tsx<div aria-live="polite" aria-atomic="true" className="visually-hidden">
{resultCount === 0 ? 'Sin resultados' : `${resultCount} resultados`}
</div>
Usa polite para actualizaciones normales y assertive solo para errores críticos.
5. Prueba con herramientas y teclado
Automatiza lo básico con axe-core o eslint-plugin-jsx-a11y, pero valida manualmente:
- Navegación solo con teclado
- VoiceOver (macOS) o NVDA (Windows)
- Contraste con Lighthouse o DevTools
Un aria-label bien escrito no compensa contraste bajo o headings saltados.
Conclusión
Accesibilidad en React es trabajo de producto: HTML correcto, foco predecible, estados anunciados y pruebas continuas.
Empieza con HTML nativo, prioriza el teclado y prueba con personas reales cuando puedas. Interfaces accesibles suelen ser más robustas para todos.




Comentarios
Inicia sesión con tu cuenta de GitHub para comentar. Los comentarios son públicos y se guardan como Discussions en el repositorio de comentarios del blog.