frontend / html
Accessibilité : ARIA, roles et landmarks
Explication
Ce que vous allez apprendre
- Appliquer la règle d'or « No ARIA is better than bad ARIA »
- Préférer systématiquement un élément HTML natif à une reconstruction ARIA maison
- Utiliser les landmarks ARIA (
banner,navigation,main,complementary) pour la navigation assistée - Distinguer plusieurs zones du même type avec
aria-label - Annoncer un changement dynamique avec
aria-livesans saturer l'utilisateur de lecteur d'écran
Dans quel contexte ?
Un développeur construit un composant d'onglets personnalisé pour la page parametres-compte.html, avec des <div onclick="..."> stylées en CSS. Un test avec le lecteur d'écran NVDA révèle qu'aucun onglet n'est annoncé comme cliquable et qu'on ne peut pas y accéder au clavier. En ajoutant role="tab", aria-selected et aria-controls, puis en gérant manuellement le focus au clavier, le composant redevient utilisable — mais seulement parce que le comportement clavier a été recodé à la main, contrairement à un <button> natif qui l'aurait offert gratuitement.
Étape 1 : à quoi sert vraiment ARIA
ARIA (Accessible Rich Internet Applications) est un ensemble d'attributs qui rend accessible du contenu que le HTML natif ne sait pas décrire — des onglets personnalisés, des menus complexes, des widgets sur-mesure.
Étape 2 : la règle d'or à graver dans le marbre
Avant d'aller plus loin, retenez cette règle : « No ARIA is better than bad ARIA » — pas d'ARIA vaut mieux qu'un mauvais ARIA. Ajouter role="button" à une <div> NE la rend PAS automatiquement utilisable au clavier : ARIA décrit un rôle, mais n'implémente aucun comportement.
Étape 3 : pourquoi le HTML natif gagne presque toujours
Comparons. Un vrai <button> gère déjà tout seul le focus au clavier (touche Tab), l'activation avec Entrée ou Espace, et l'annonce correcte "bouton" par les lecteurs d'écran.
Reproduire ce comportement à la main avec une <div> et des attributs ARIA demande de recoder chaque interaction clavier manuellement — et le risque d'en oublier une est élevé. D'où la règle pratique : n'utiliser ARIA que quand aucun élément HTML natif équivalent n'existe.
Piège fréquent
Ajouter role="button" à une <div> ne rend PAS le clic possible au clavier avec Entrée ou Espace, et ne donne pas non plus le focus via Tab. ARIA décrit un rôle sémantique, il n'implémente jamais aucun comportement — c'est toujours à vous de le coder en JavaScript si vous n'utilisez pas <button>.
Étape 4 : les landmarks, une carte pour naviguer sans les yeux
Une fois ce principe posé, voyons les landmarks. Des rôles comme banner, navigation, main ou complementary créent des points de repère qu'un utilisateur de lecteur d'écran peut lister et atteindre directement, comme une table des matières interactive.
Étape 5 : le cas des zones dupliquées
Il reste un cas particulier : quand une page contient plusieurs zones du même type, par exemple deux <nav>. Là, un aria-label devient indispensable pour les distinguer — sinon l'utilisateur entend juste "navigation, navigation" sans savoir laquelle est laquelle.
| Rôle ARIA / landmark | Élément HTML natif équivalent | Usage |
|---|---|---|
role="banner" | <header> (racine) | En-tête de page |
role="navigation" | <nav> | Zone de liens de navigation |
role="main" | <main> | Contenu principal unique |
role="complementary" | <aside> | Contenu annexe lié |
role="contentinfo" | <footer> (racine) | Pied de page |
Étape 6 : le piège des live regions
Dernier point délicat : aria-live permet d'annoncer un changement dynamique sans que l'utilisateur navigue manuellement vers cette zone. Mais l'utiliser pour chaque petite mise à jour sature l'utilisateur d'annonces vocales inutiles — à réserver aux informations vraiment importantes : une erreur, une confirmation.
Et ensuite ?
Une fois ARIA compris, la prochaine étape consiste à approfondir un sujet lié : la gestion experte du focus clavier.
Commandes & code
Accessibilité : ARIA, roles et landmarks
Règle d'or ARIA : « No ARIA is better than bad ARIA ». On ne l'utilise que quand le HTML natif ne suffit pas.
<!-- Règle n°1 : préférer le HTML natif à ARIA -->
<!-- MAUVAIS -->
<div onclick="submit()" role="button" tabindex="0">Envoyer</div>
<!-- BON : le navigateur gère déjà focus, clavier, rôle -->
<button onclick="submit()">Envoyer</button>
<!-- ARIA devient nécessaire pour des widgets sans équivalent HTML -->
<div role="tablist" aria-label="Paramètres du compte">
<button role="tab" aria-selected="true" aria-controls="panel-profil" id="tab-profil">
Profil
</button>
<button role="tab" aria-selected="false" aria-controls="panel-securite" id="tab-securite">
Sécurité
</button>
</div>
<div role="tabpanel" id="panel-profil" aria-labelledby="tab-profil">
<p>Contenu du profil</p>
</div>
<div role="tabpanel" id="panel-securite" aria-labelledby="tab-securite" hidden>
<p>Contenu sécurité</p>
</div><!-- Landmarks : la carte de navigation pour lecteur d'écran -->
<header role="banner">...</header>
<!-- ↑ role implicite déjà avec <header> au 1er niveau du body, mais explicite ici pour l'exemple -->
<nav aria-label="Principale">...</nav>
<nav aria-label="Fil d'ariane">...</nav>
<!-- ↑ plusieurs <nav> ? aria-label OBLIGATOIRE pour les distinguer au clavier -->
<main role="main">...</main>
<aside role="complementary">...</aside>
<footer role="contentinfo">...</footer>
<!-- Attributs live regions : annoncer des changements dynamiques -->
<div aria-live="polite" id="notifications">
<!-- injecté en JS : annoncé sans interrompre le flux de lecture -->
</div>
<div aria-live="assertive" role="alert">
<!-- pour les erreurs critiques : interrompt immédiatement le lecteur d'écran -->
</div>
<!-- États dynamiques -->
<button aria-expanded="false" aria-controls="menu-mobile" id="toggle-menu">
Menu
</button>
<ul id="menu-mobile" hidden>
<li><a href="/">Accueil</a></li>
</ul>
<input type="checkbox" aria-invalid="true" aria-describedby="erreur-cgu">
<span id="erreur-cgu">Vous devez accepter les CGU</span>| Attribut ARIA | Usage |
|---|---|
aria-label | nom accessible quand pas de texte visible |
aria-labelledby | référence un élément qui sert de label |
aria-describedby | référence un texte descriptif (aide, erreur) |
aria-expanded | état ouvert/fermé d'un widget |
aria-live | annonce les changements dynamiques |
Résumé
- HTML natif d'abord :
<button>,<nav>,<main>embarquent déjà les bons rôles. - ARIA ne change JAMAIS le comportement clavier/focus : ça reste à la charge du JS.
- Plusieurs landmarks du même type exigent un
aria-labelpour les différencier. aria-liveest réservé aux mises à jour vraiment utiles à annoncer (pas de spam).
Exercices pratiques
Mission : rendre utilisable le composant d'onglets de parametres-compte.html
Objectif : Corriger un composant d'onglets construit avec des div onclick, inaccessible au clavier et invisible pour NVDA.
Contexte
Le composant d'onglets de parametres-compte.html est fait de <div onclick="..."> stylées en CSS. Un test avec le lecteur d'écran NVDA révèle qu'aucun onglet n'est annoncé comme cliquable, et qu'on ne peut pas y accéder au clavier.
Ta mission : corriger ce composant avec les bons rôles et attributs ARIA.