Accesibilidad en JavaScript: cómo hacer un sitio web cómodo para todos
\n\nImagine que entra a un sitio web y el botón «Comprar» no se puede presionar con el mouse, solo con el teclado. O que no ve la pantalla y el lector de pantalla simplemente se salta la mitad del contenido. Desagradable, ¿verdad? Pues para millones de personas, esta es la realidad diaria.
\n\nLa accesibilidad (o a11y) no es solo un término de moda. Es una forma de hacer que su código sea honesto. La accesibilidad en JavaScript se trata de que su sitio web funcione para todos: para personas con discapacidad visual, con problemas motores, para aquellos que solo usan el teclado o el control por voz. Y sí, también se trata de SEO: a los motores de búsqueda les encanta el código limpio y semánticamente correcto.
\n\nEn este artículo, analizaremos ejemplos reales en JavaScript que puede implementar hoy mismo. Sin rodeos, solo código y práctica.
\n\n¿Por qué la accesibilidad es su responsabilidad?
\n\nSi escribe en JavaScript, usted controla el comportamiento de la interfaz. Es JS el que más a menudo rompe la accesibilidad: modales dinámicos, desplazamientos infinitos, selectores personalizados. Los lectores de pantalla no pueden leer sus pensamientos: leen lo que usted les dice a través de HTML y ARIA.
\n\nLa buena noticia: la mayoría de los problemas se pueden solucionar en una tarde. La mala: si no piensa en la accesibilidad desde el principio, tendrá que reescribir el código durante semanas.
\n\nAtributos ARIA: su herramienta principal
\n\nARIA (Accessible Rich Internet Applications) es un conjunto de atributos que ayudan a las tecnologías de asistencia a entender lo que sucede en la página. JavaScript es ideal para actualizar dinámicamente estos atributos.
\n\nEjemplo 1: Actualización dinámica de aria-live
\n\nSupongamos que tiene un chat donde los mensajes se cargan sin recargar la página. El lector de pantalla debe anunciar el nuevo mensaje. Sin aria-live, el usuario simplemente no se enterará de la actualización.
// Creamos un contenedor para notificaciones\nconst liveRegion = document.createElement('div');\nliveRegion.setAttribute('aria-live', 'polite');\nliveRegion.setAttribute('aria-atomic', 'true');\nliveRegion.classList.add('sr-only'); // ocultamos visualmente\ndocument.body.appendChild(liveRegion);\n\n// Función para agregar un mensaje\nfunction addChatMessage(message) {\n liveRegion.textContent = ''; // limpiamos\n liveRegion.textContent = `Nuevo mensaje: ${message}`;\n}\n\n// Ejemplo de llamada\naddChatMessage('¡Hola! ¿Cómo estás?');\n\nImportante: aria-live="polite" le dice al lector de pantalla: «Anuncia cuando termines de leer lo actual». aria-live="assertive" interrumpe la lectura; úselo para errores críticos.
Ejemplo 2: Acordeón/desplegable personalizado
\n\nLos elementos estándar <details> y <summary> ya son accesibles, pero si crea un acordeón personalizado en JS, debe agregar roles y estados ARIA.
// Para cada sección del acordeón\nconst accordionButton = document.querySelector('.accordion-button');\nconst accordionPanel = document.querySelector('.accordion-panel');\n\naccordionButton.setAttribute('aria-expanded', 'false');\naccordionButton.setAttribute('aria-controls', 'panel-1');\naccordionPanel.setAttribute('id', 'panel-1');\naccordionPanel.setAttribute('aria-hidden', 'true');\n\naccordionButton.addEventListener('click', () => {\n const isOpen = accordionButton.getAttribute('aria-expanded') === 'true';\n accordionButton.setAttribute('aria-expanded', !isOpen);\n accordionPanel.setAttribute('aria-hidden', isOpen);\n});\n\nAhora el lector de pantalla entiende que el botón controla el panel y sabe si está abierto o cerrado.
\n\nGestión del foco: no deje que el usuario se pierda
\n\nUno de los errores más comunes en la accesibilidad de JavaScript es la pérdida del foco. Cuando se abre una ventana modal, el foco debe moverse al interior. Cuando se cierra, debe volver al botón que la invocó.
\n\n