Accessibilité en JavaScript : comment rendre un site accessible à tous
\n\nImaginez que vous arrivez sur un site, et que le bouton « Acheter » ne s'active pas avec la souris — seulement avec le clavier. Ou que vous ne voyez pas l'écran, et que le lecteur d'écran ignore la moitié du contenu. Désagréable, n'est-ce pas ? Pourtant, pour des millions de personnes, c'est une réalité quotidienne.
\n\nL'accessibilité (ou a11y) n'est pas qu'un terme à la mode. C'est une façon de rendre votre code honnête. L'accessibilité en JavaScript consiste à faire en sorte que votre site fonctionne pour tout le monde : pour les personnes malvoyantes, ayant des troubles moteurs, pour celles qui utilisent uniquement le clavier ou la commande vocale. Et oui, cela concerne aussi le SEO : les moteurs de recherche aiment le code propre et sémantiquement correct.
\n\nDans cet article, nous allons voir des exemples concrets en JavaScript que vous pouvez mettre en œuvre dès aujourd'hui. Pas de blabla — que du code et de la pratique.
\n\nPourquoi l'accessibilité est votre responsabilité ?
\n\nSi vous codez en JavaScript, vous gérez le comportement de l'interface. C'est souvent le JS qui casse l'accessibilité : modales dynamiques, défilements infinis, sélecteurs personnalisés. Les lecteurs d'écran ne lisent pas dans vos pensées — ils lisent ce que vous leur dites via le HTML et les attributs ARIA.
\n\nBonne nouvelle : la plupart des problèmes peuvent être corrigés en une soirée. Mauvaise : si vous ne pensez pas à l'accessibilité dès le départ, la réécriture peut prendre des semaines.
\n\nLes attributs ARIA : votre outil principal
\n\nARIA (Accessible Rich Internet Applications) est un ensemble d'attributs qui aident les technologies d'assistance à comprendre ce qui se passe sur la page. JavaScript est parfait pour mettre à jour dynamiquement ces attributs.
\n\nExemple 1 : Mise à jour dynamique d'aria-live
\n\nSupposons que vous ayez un chat où les messages sont chargés sans rechargement de page. Le lecteur d'écran doit annoncer le nouveau message. Sans aria-live, l'utilisateur ne saura tout simplement pas qu'il y a une mise à jour.
// Création d'un conteneur pour les notifications\nconst liveRegion = document.createElement('div');\nliveRegion.setAttribute('aria-live', 'polite');\nliveRegion.setAttribute('aria-atomic', 'true');\nliveRegion.classList.add('sr-only'); // caché visuellement\ndocument.body.appendChild(liveRegion);\n\n// Fonction pour ajouter un message\nfunction addChatMessage(message) {\n liveRegion.textContent = ''; // efface\n liveRegion.textContent = `Nouveau message : ${message}`;\n}\n\n// Exemple d'appel\naddChatMessage('Salut ! Comment ça va ?');\n\nImportant : aria-live="polite" dit au lecteur d'écran : « Annonce quand tu auras fini de lire le contenu actuel ». aria-live="assertive" interrompt la lecture — à utiliser pour les erreurs critiques.
Exemple 2 : Accordéon personnalisé
\n\nLes éléments standards <details> et <summary> sont déjà accessibles, mais si vous créez un accordéon personnalisé en JS, vous devez ajouter les rôles et états ARIA.
// Pour chaque section de l'accordéon\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\nMaintenant, le lecteur d'écran comprend que le bouton contrôle le panneau et sait s'il est ouvert ou fermé.
\n\nGestion du focus : ne laissez pas l'utilisateur se perdre
\n\nL'une des erreurs les plus courantes en accessibilité JavaScript est la perte du focus. Lorsqu'une fenêtre modale s'ouvre, le focus doit se déplacer à l'intérieur. Lorsqu'elle se ferme, il doit revenir au bouton qui l'a déclenchée.
\n\n