Retour au cours

frontend / html

Accessibilité : ARIA, roles et landmarks

Leçon 81 exercice

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-live sans 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 équivalentUsage
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.

html
<!-- 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>
html
<!-- 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 ARIAUsage
aria-labelnom accessible quand pas de texte visible
aria-labelledbyréférence un élément qui sert de label
aria-describedbyréférence un texte descriptif (aide, erreur)
aria-expandedétat ouvert/fermé d'un widget
aria-liveannonce 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-label pour les différencier.
  • aria-live est réservé aux mises à jour vraiment utiles à annoncer (pas de spam).

Exercices pratiques

1 disponible
1

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.

Résoudre l’exercice →