Accessibilité web : les bases qu’un développeur ne devrait pas rater
Un guide d’introduction à l’accessibilité web pour les développeurs : HTML sémantique, navigation au clavier et focus visible, contrastes, formulaires, bon usage d’ARIA, animations, particularités de React et Next.js, et les premiers outils pour tester.
L’accessibilité web consiste à rendre un site utilisable par tous, y compris par les personnes qui naviguent au clavier, avec un lecteur d’écran, un zoom important ou une sensibilité au mouvement. Ce n’est pas une spécialité réservée aux experts : l’essentiel dépend de choix que le développeur fait chaque jour. Ce guide rassemble les bases à ne pas rater, avec des exemples tirés de ce site, sans prétendre remplacer un audit complet.
Pourquoi c’est l’affaire du développeur ?
La référence internationale est le WCAG (Web Content Accessibility Guidelines), dans sa version 2.2, dont le niveau AA est celui généralement visé. En France, le RGAA (Référentiel général d’amélioration de l’accessibilité) en reprend les critères. L’obligation, longtemps limitée au secteur public et aux grandes entreprises, s’étend : la directive européenne sur l’accessibilité (European Accessibility Act), applicable depuis juin 2025, couvre désormais de nombreux services numériques privés, dont le e-commerce.
Au-delà du droit, l’accessibilité profite à tout le monde. Un contraste suffisant aide en plein soleil, une navigation au clavier sert les utilisateurs avancés, et un HTML bien structuré est aussi celui que les moteurs de recherche comprennent le mieux. Or la plupart de ces points se jouent dans le code, au moment où l’on choisit une balise ou où l’on stylise un état.
Le HTML sémantique d’abord
Les éléments HTML natifs embarquent leur comportement et leur rôle. Un button se déclenche au clavier avec Entrée ou Espace et s’annonce comme un bouton ; un div cliquable ne fait rien de tout cela. Les bases tiennent en quelques réflexes :
- un button pour une action, un lien a pour une navigation, jamais l’inverse ;
- des titres h1 à h6 hiérarchisés, sans saut de niveau, qui forment le plan de la page ;
- des listes ul ou ol pour les suites d’éléments, des tableaux uniquement pour des données tabulaires ;
- des zones de page (header, nav, main, footer) qui permettent à un lecteur d’écran d’aller directement à l’essentiel ;
- un attribut lang sur la balise html, pour que la synthèse vocale prononce correctement le texte.
Clavier et focus : tout doit marcher sans souris
Une personne qui ne peut pas utiliser de souris parcourt la page avec Tab, Maj + Tab, Entrée et les flèches. Chaque élément interactif doit donc être atteignable au clavier, dans un ordre qui suit la lecture, et sans piège dont on ne peut plus sortir. Le focus, c’est-à-dire l’indicateur de l’élément actif, doit rester visible en permanence : supprimer le contour avec outline: none sans le remplacer rend la page inutilisable au clavier.
Sur ce site, chaque élément interactif affiche un anneau de focus avec :focus-visible, qui n’apparaît qu’à la navigation au clavier et pas au clic. Un lien d’évitement « Aller au contenu », premier élément atteint avec Tab, permet aussi de sauter le menu. Le WCAG 2.2 ajoute deux exigences utiles : l’élément qui a le focus ne doit pas être masqué, par exemple par un en-tête fixe, et les cibles cliquables doivent mesurer au moins 24 × 24 pixels.
Images, contrastes et couleurs
- Une image qui porte une information reçoit un alt qui la décrit ; une image décorative reçoit un alt vide (alt=""), pour que le lecteur d’écran l’ignore.
- Le texte doit présenter un contraste d’au moins 4,5:1 avec son fond, et de 3:1 pour les grands textes, les icônes et les bordures des composants. Un thème sombre n’y échappe pas : un gris trop clair sur fond noir est un piège fréquent.
- La couleur ne doit jamais être le seul moyen de transmettre une information : un champ en erreur affiche aussi un message, en plus de sa bordure rouge.
Des formulaires utilisables par tous
Chaque champ a un label associé, visible et relié au champ par l’attribut for ; un placeholder ne le remplace pas, puisqu’il disparaît à la saisie. Les erreurs sont décrites en texte, reliées au champ concerné par aria-describedby, et annoncées aux lecteurs d’écran grâce à une zone role="alert" ou aria-live. Le champ fautif peut enfin recevoir le focus, pour que l’utilisateur sache où corriger.
ARIA, avec parcimonie
ARIA (Accessible Rich Internet Applications) ajoute des rôles et des états aux éléments, pour les cas que le HTML ne couvre pas. Sa première règle est de ne pas s’en servir quand un élément natif suffit, car ARIA ne fait qu’annoncer, sans rien implémenter. Un div doté de role="button" s’annonce comme un bouton, mais il faut encore lui ajouter le focus au clavier, la gestion d’Entrée et d’Espace et l’état désactivé, ce qu’un button fait nativement.
Utilisé à bon escient, ARIA rend de vrais services. Les filtres de la page du blog sont des boutons dotés d’aria-pressed, qui annonce le filtre actif, et le nombre d’articles affichés se trouve dans une zone role="status", lue après chaque changement. Les liens qui ouvrent un nouvel onglet portent la mention « (nouvel onglet) », masquée à l’écran mais lue par les lecteurs d’écran.
Le mouvement et les animations
Les animations peuvent provoquer vertiges et nausées chez certaines personnes, qui règlent alors leur système pour les réduire. La requête media prefers-reduced-motion transmet ce réglage à la page, qui doit en tenir compte en désactivant les animations non essentielles. Sur ce site, aucune animation ne démarre avec cette préférence, et le contenu reste affiché tel quel ; l’article sur GSAP détaille comment.
Les particularités de React et Next.js
- Les fragments React évitent les div superflues qui cassent la structure, par exemple entre un ul et ses li.
- Les règles jsx-a11y d’ESLint, incluses dans la configuration eslint-config-next, signalent dès l’écriture une image sans alt ou un élément cliquable non accessible.
- Lors d’une navigation côté client, la page ne se recharge pas : Next.js annonce le titre de la nouvelle page aux lecteurs d’écran grâce à un route announcer intégré, d’où l’intérêt d’un titre propre à chaque page.
- Une modale ou un menu ouvert doit déplacer le focus à l’intérieur, se fermer avec Échap, puis rendre le focus à l’élément qui l’a ouvert ; les composants headless éprouvés (Radix, React Aria) le font déjà.
Comment tester l’accessibilité ?
Le premier test ne demande aucun outil : débrancher la souris et parcourir la page avec Tab. On vérifie que chaque élément interactif est atteignable, que l’ordre est logique, que le focus reste visible et qu’aucune fonction ne dépend du survol.
Les outils automatiques prennent ensuite le relais. axe, développé par Deque, est le moteur de référence : il fait tourner l’audit Accessibilité de Lighthouse, existe en extension de navigateur et s’intègre aux tests de bout en bout. Sur mon socle de sites vitrines, chaque parcours Playwright passe ainsi les pages à axe, et la CI échoue au moindre problème détecté.
Ces outils ne détectent toutefois qu’une partie des problèmes. Ils repèrent une image sans alt, mais pas un alt qui décrit mal l’image, ni un ordre de lecture déroutant. L’étape suivante consiste à essayer un lecteur d’écran, NVDA sous Windows ou VoiceOver sous macOS, puis, pour un projet soumis à une obligation légale, à faire réaliser un audit par un spécialiste.