Édition · avril 2026 · Paris

Guide framework · Debutant a avance

Accessibilite React : guide RGAA complet

Guide complet pour rendre vos applications React accessibles selon le RGAA : semantique HTML, focus, formulaires, aria-live et checklist.

20 min de lecture · React 19+, TypeScript

  1. Pourquoi l'accessibilité est cruciale en React

React a révolutionné le développement front-end en introduisant un modèle déclaratif basé sur des composants réutilisables et un Virtual DOM. Cette abstraction offre des gains énormes en productivité et en maintenabilité, mais elle crée aussi une distance entre le développeur et le HTML réel généré dans le navigateur. Or, l'accessibilité repose fondamentalement sur la qualité du HTML : structure sémantique, attributs ARIA, ordre logique du DOM, gestion du focus.

En France, le RGAA 4.1.2 impose des critères stricts d'accessibilité qui s'appliquent à toute application web, quelle que soit la technologie utilisée. Une application React qui ne respecte pas ces critères expose son organisation à des sanctions administratives prévues par l'European Accessibility Act, jusqu'à 37 500 € par manquement pour une personne morale, avec astreintes journalières possibles.

Au-delà de l'aspect légal, l'accessibilité concerne environ 16 % de la population mondiale en situation de handicap (OMS, 2023). Les déficiences visuelles, motrices, auditives et cognitives impactent la façon dont les utilisateurs interagissent avec vos interfaces. Un composant React peut paraître parfait visuellement mais être totalement inutilisable avec un lecteur d'écran ou un clavier.

Ce guide couvre les spécificités de l'accessibilité dans le contexte React : les pièges à éviter, les patterns à adopter, les critères RGAA les plus concernés et les outils pour automatiser une partie de la vérification. L'objectif est de vous donner les connaissances nécessaires pour intégrer l'accessibilité dans votre workflow de développement React au quotidien.

  1. Erreurs d'accessibilité courantes en React

Voici les erreurs les plus fréquemment rencontrées dans les applications React, et pourquoi elles posent problème :

Images sans alternative textuelle

En React, il est facile d'oublier l'attribut

alt

sur les balises

<img>

ou sur le composant

next/image

. Sans alternative textuelle, les lecteurs d'écran annoncent le chemin du fichier ou rien du tout. Pour les images décoratives, utilisez

alt=""

explicitement plutôt que d'omettre l'attribut, afin que le lecteur d'écran ignore l'image.

Utilisation de div et span comme éléments interactifs

L'une des erreurs les plus répandues est d'attacher un

onClick

sur un

<div>

ou un

<span>

. Ces éléments ne sont pas focusables par défaut, ne déclenchent pas d'action au clavier (Entrée ou Espace) et ne sont pas annoncés comme interactifs par les lecteurs d'écran. Il faudrait alors ajouter

role="button"

,

tabIndex={0}

et un gestionnaire

onKeyDown

. Mais la solution la plus simple et la plus robuste est d'utiliser un

<button>

natif.

Absence de gestion du focus après navigation SPA

Dans une Single Page Application, le changement de route ne déclenche pas de rechargement de page. Les lecteurs d'écran ne sont donc pas automatiquement informés que le contenu a changé. Le focus reste sur l'élément qui a déclenché la navigation (un lien, par exemple), et l'utilisateur ne sait pas que du nouveau contenu est apparu. C'est une violation du critère RGAA 12.1 sur la navigation.

Mauvaise utilisation des attributs ARIA en JSX

React utilise le camelCase pour la plupart des attributs HTML, mais les attributs

aria-*

et

data-*

conservent leur syntaxe avec des tirets. Cela peut créer de la confusion. De plus, certains développeurs ajoutent des attributs ARIA de façon excessive ou incorrecte, ce qui peut dégrader l'expérience plutôt que l'améliorer. La règle d'or : pas d'ARIA est mieux que du mauvais ARIA.

Contenu dynamique non annoncé

React excelle dans les mises à jour dynamiques de l'interface : notifications, messages de validation, chargement de données. Mais sans regions

aria-live

, ces changements sont invisibles pour les utilisateurs de lecteurs d'écran. Le contenu apparaît à l'écran mais n'est jamais annoncé, rendant l'application inutilisable pour les personnes malvoyantes.

  1. Bonnes pratiques avec exemples de code

Privilégier le HTML sémantique

Le HTML sémantique est la fondation de l'accessibilité. Utilisez

<button>

,

<nav>

,

<main>

,

<header>

,

<section>

plutôt que des

<div>

partout. Les éléments natifs embarquent des comportements d'accessibilité gratuits : focus, rôles ARIA implicites, interactions clavier.

Gestion du focus avec useRef et useEffect

Après une navigation SPA ou l'ouverture d'une modale, il est essentiel de déplacer le focus au bon endroit. React fournit

useRef

et

useEffect

pour gérer cela de manière déclarative.

L'attribut

tabIndex={-1}

rend l'élément focusable par JavaScript sans l'ajouter à l'ordre de tabulation naturel. C'est le pattern recommandé pour les titres qui doivent recevoir le focus programmatiquement.

Régions aria-live pour le contenu dynamique

Utilisez

aria-live

pour informer les lecteurs d'écran des changements de contenu.

polite

attend que le lecteur termine sa phrase actuelle,

assertive

interrompt immédiatement (à utiliser avec parcimonie).

Formulaires accessibles

Les formulaires sont une source majeure de problèmes d'accessibilité. Chaque champ doit avoir un label explicite, les erreurs doivent être associées aux champs via

aria-describedby

, et les champs obligatoires doivent utiliser

aria-required

ou l'attribut natif

required

.

Points importants : l'attribut

htmlFor

(équivalent de

for

en HTML) associe le label au champ. L'étoile décorative est masquée avec

aria-hidden="true"

pour éviter que les lecteurs d'écran annoncent "étoile". Le vrai signal d'obligation est porté par

aria-required

.

Navigation clavier avec onKeyDown

Quand vous créez des composants interactifs personnalisés (onglets, menus, sliders), vous devez implémenter la navigation clavier. Suivez les patterns du WAI-ARIA Authoring Practices pour chaque type de composant.

Ce pattern utilise le roving tabindex : seul l'onglet actif a

tabIndex={0}

, les autres ont

tabIndex={-1}

. L'utilisateur navigue entre les onglets avec les flèches et entre/sort du groupe avec Tab.

React.Fragment pour éviter les noeuds DOM superflus

Les

<div>

d'encapsulation inutiles polluent l'arbre DOM et peuvent perturber les structures sémantiques (par exemple, insérer un

<div>

entre un

<ul>

et ses

<li>

). Utilisez

React.Fragment

ou la syntaxe courte

<>...</>

pour grouper des éléments sans ajouter de noeud DOM.

  1. Critères RGAA essentiels pour React

Parmi les 106 critères du RGAA, certains sont particulièrement impactés par l'utilisation de React. Voici les quatre critères les plus critiques et leurs implications pour les développeurs React :

Critère 1.1 — Images : alternative textuelle

Chaque image porteuse d'information doit posséder une alternative textuelle pertinente. En React, cela concerne les balises

<img>

, le composant

next/image

, les SVG inlines et les icônes. Les images décoratives doivent avoir

alt=""

ou

aria-hidden="true"

.

Critère 7.1 — Scripts : compatibilité avec les technologies d'assistance

Ce critère est central pour React puisque toute l'application est générée par JavaScript. Chaque composant interactif doit être utilisable au clavier, avoir un nom accessible, un rôle et un état ARIA corrects. Les changements de contenu dynamiques doivent être restitués par les technologies d'assistance.

Concrètement, chaque bouton, lien, menu déroulant, onglet, accordéon ou modale doit fonctionner intégralement au clavier. Testez avec Tab, Shift+Tab, Entrée, Espace, Échap et les flèches directionnelles. Si un composant ne fonctionne pas sans souris, il viole ce critère.

Critère 11.1 — Formulaires : présence d'étiquettes

Chaque champ de formulaire doit posséder une étiquette (label). En React, utilisez

htmlFor

sur le

<label>

associé à l'

id

du champ. Ne remplacez jamais un label par un simple placeholder : les placeholders disparaissent à la saisie et n'ont pas de rôle sémantique de label.

Critère 12.1 — Navigation : présence d'un système de navigation

Chaque ensemble de pages doit proposer au moins deux systèmes de navigation parmi : menu, plan du site, moteur de recherche. En React SPA, le routeur côté client ne déclenche pas de rechargement de page. Vous devez donc gérer manuellement l'annonce des changements de page, la mise à jour du titre et le déplacement du focus. Les liens d'évitement ("Aller au contenu principal") doivent être fonctionnels et visibles au focus. Vérifiez que votre barre de navigation utilise une balise

<nav>

avec un

aria-label

distinct pour chaque zone de navigation.

  1. Outils et packages recommandés

L'écosystème React dispose d'outils puissants pour intégrer l'accessibilité à chaque étape du développement. Voici les packages incontournables :

1

eslint-plugin-jsx-a11y

Plugin ESLint qui détecte les erreurs d'accessibilité directement dans votre éditeur de code. Il vérifie la présence des attributs alt, les rôles ARIA valides, les éléments interactifs sans gestionnaire clavier, et bien d'autres règles. À intégrer dans votre CI/CD pour bloquer les régressions.

2

@testing-library/react

Librairie de test qui encourage les bonnes pratiques en utilisant les requêtes basées sur les rôles ARIA et les labels accessibles plutôt que sur les sélecteurs CSS ou les test-ids. Si votre composant n'est pas trouvable par

getByRole

ou

getByLabelText

, c'est probablement un signe de problème d'accessibilité.

3

@axe-core/react

Intègre le moteur d'audit axe-core directement dans votre application React en mode développement. À chaque rendu, il analyse le DOM et affiche les violations d'accessibilité dans la console du navigateur. Idéal pour détecter les problèmes au fil du développement sans ouvrir un outil externe.

4

React Aria (Adobe)

Collection de hooks React qui implémentent les patterns ARIA de manière accessible. Plutôt que de construire vos propres composants avec des roles et des interactions clavier complexes, React Aria fournit des hooks comme

useButton

,

useDialog

,

useComboBox

,

useMenu

qui gèrent le focus, le clavier et les attributs ARIA automatiquement. C'est la référence en matière de composants accessibles sans style imposé.

  1. Checklist accessibilité React

Utilisez cette checklist comme référence lors du développement et de la revue de code de vos composants React :

Structure et sémantique

  • Utilisation de balises HTML sémantiques (

    button

    ,

    nav

    ,

    main

    ,

    header

    ,

    footer

    ) au lieu de

    div

    pour les éléments interactifs et les landmarks

  • Hiérarchie de titres logique (h1 à h6) sans saut de niveaux

  • Utilisation de Fragment au lieu de div d'encapsulation quand le noeud DOM n'est pas nécessaire

  • Lien d'evitement "Aller au contenu principal" present et fonctionnel

Images et médias

  • Toutes les images informatives ont un attribut

    alt

    descriptif

  • Les images décoratives ont

    alt=""

    ou

    aria-hidden="true"

  • Les SVG interactifs ou informatifs ont

    role="img"

    et un

    aria-label

    ou un

    <title>

  • Les icônes dans les boutons avec texte ont

    aria-hidden="true"

    et

    focusable="false"

Formulaires

  • Chaque champ a un

    <label>

    explicitement associé via

    htmlFor

  • Les erreurs de validation sont associées aux champs via

    aria-describedby

  • Les champs invalides utilisent

    aria-invalid="true"

  • Les champs obligatoires utilisent

    required

    ou

    aria-required="true"

  • Les groupes de champs radio/checkbox sont dans un

    <fieldset>

    avec

    <legend>

Interactions et navigation

  • Tous les éléments interactifs sont accessibles au clavier (Tab, Entrée, Espace, Échap)

  • Le focus est visible sur tous les éléments interactifs (outline visible)

  • Le focus est géré après chaque changement de route SPA

  • Les modales implémentent un focus trap et restaurent le focus a la fermeture

  • L'ordre de tabulation suit l'ordre visuel logique

Contenu dynamique et ARIA

  • Les mises à jour dynamiques utilisent

    aria-live

    pour être annoncées

  • Les états de chargement sont communiqués (

    aria-busy

    , texte de chargement accessible)

  • Les rôles ARIA ne sont utilisés que quand le HTML sémantique ne suffit pas

  • Le titre de la page (

    document.title

    ) est mis à jour à chaque changement de route

Tests et outillage

  • eslint-plugin-jsx-a11y activé dans la CI/CD

  • Tests unitaires utilisant

    getByRole

    et

    getByLabelText

    plutôt que

    getByTestId

  • Test manuel au clavier effectué sur chaque composant interactif

  • Test avec au moins un lecteur d'écran (NVDA, VoiceOver ou JAWS)