Tableau de données accessible : caption, th et scope
Baliser un tableau de données accessible : caption associé, en-têtes th avec scope, critères RGAA de la thématique 5 et défilement maîtrisé à 320 px.
Un tableau de données présente des informations en lignes et colonnes, sans interactivité : liste de prix, rapport, comparatif. L'élément à préférer est <table> avec <caption>, <thead> et des <th> munis de scope : c'est toute la thématique 5 du RGAA, entièrement une affaire de balisage. Aucun script, aucun modèle clavier : un tableau standard bien balisé est accessible par construction.
Cette fiche couvre le tableau standard, celui que scope suffit à décrire. Dès que des en-têtes fusionnent ou se superposent sur plusieurs niveaux, les techniques changent : le guide Tableaux complexes accessibles détaille pas à pas la simplification, les cellules fusionnées et les associations headers/id.
Quand ce motif est le mauvais choix
- Pour de la mise en page, ne pas utiliser de tableau : CSS grid et flexbox existent. Un tableau de mise en forme résiduel doit rester compréhensible une fois linéarisé et porter
role="presentation"(critère 5.3), sans aucun élément propre aux tableaux de données (critère 5.8). - Pour un tableau que l'utilisateur manipule cellule par cellule (édition, sélection, tableur), c'est le motif grille (
role="grid"), qui ajoute un modèle clavier complet. Un tableau en lecture seule ne doit jamais recevoirrole="grid". - Pour une hiérarchie de lignes dépliables avec cellules interactives, voir la fiche grille arborescente ; si les lignes se déplient mais restent en lecture seule, un simple
<table>avec des boutonsaria-expandedsuffit. - Des
<div>stylés en tableau ne sont pas un tableau : sans lignes, colonnes ni en-têtes, un lecteur d'écran lit un seul bloc de texte plat.
Critères RGAA applicables
- Critère 5.4 : titre associé au tableau. Le titre d'un tableau de données doit être correctement associé au tableau ; c'est le rôle de
<caption>, premier enfant de<table>. Un<h2>posé au-dessus n'est associé à rien. - Critère 5.5 : pertinence du titre. Ce titre doit identifier le contenu du tableau de manière claire et concise. Distinct du 5.4 : un
<caption>présent mais vague (« Tableau 3 ») échoue ici. - Critère 5.6 : déclaration des en-têtes. Chaque en-tête de colonne et chaque en-tête de ligne doit être déclaré, par
<th>(ourole="columnheader"/role="rowheader"). L'oubli classique : les en-têtes de ligne laissés en<td>. - Critère 5.7 : association des cellules aux en-têtes. La technique appropriée doit relier chaque cellule à ses en-têtes :
scope="col"/scope="row"pour un tableau simple,headerspointant lesiddes<th>pour un tableau complexe à en-têtes fusionnés ou multi-niveaux (test 5.7.4). Distinct du 5.6 : les<th>peuvent exister mais être mal reliés. - Critère 5.1 : résumé d'un tableau complexe. Un tableau de données complexe doit disposer d'un résumé.
- Critère 5.2 : pertinence du résumé. Ce résumé doit être pertinent.
- Critère 5.3 : linéarisation d'un tableau de mise en forme. Contenu linéarisé compréhensible et
role="presentation"sur le tableau de mise en forme. - Critère 5.8 : éléments interdits en mise en forme. Interdiction d'y employer
<caption>,<th>,<thead>,<tfoot>,scope,headersouaxis. - Critère 10.11 : contenu consultable sans défilement horizontal à 320 px. Les tableaux de données figurent parmi les cas particuliers de ce critère (leur agencement requiert deux dimensions) ; le tableau lui-même peut donc défiler horizontalement. En revanche, le reste de la page ne doit pas être entraîné : envelopper le tableau dans un conteneur défilant.
Interaction clavier attendue
Aucune interaction propre : un tableau de données se lit avec les touches habituelles de navigation, et les raccourcis de navigation de tableau du lecteur d'écran.
| Touche | Action |
|---|---|
| Tab | Ne s'arrête pas sur le tableau lui-même. Une seule exception : le conteneur défilant d'un tableau large, qui doit être focusable. |
| Flèches | Dans un conteneur défilant focalisé : font défiler les colonnes hors écran. |
L'exception est importante : un conteneur overflow-x: auto défile à la molette ou au doigt, mais sans tabindex="0" l'utilisateur au clavier n'a aucun moyen d'atteindre les colonnes de droite.
Rôles et attributs ARIA
Aucun ARIA n'est nécessaire sur un <table> bien balisé : les rôles table, row, cell, columnheader et rowheader sont implicites. Structure de référence :
<table>
<!-- PREMIER enfant de <table> : c'est le nom du tableau (critère 5.4),
non interchangeable avec un titre posé au-dessus. -->
<caption>Chiffre d'affaires par région, T3 2026</caption>
<thead>
<tr>
<th scope="col">Région</th>
<th scope="col">Chiffre d'affaires</th>
<th scope="col">Croissance</th>
</tr>
</thead>
<tbody>
<tr>
<!-- scope="row" : l'oubli le plus courant. Sans lui, « 2,4 M€ »
est annoncé sans jamais rattacher la région. -->
<th scope="row">Europe</th>
<td>2,4 M€</td>
<td>+12 %</td>
</tr>
<tr>
<th scope="row">Asie-Pacifique</th>
<td>1,8 M€</td>
<td>+31 %</td>
</tr>
</tbody>
<tfoot>
<tr>
<th scope="row">Total</th>
<td>4,2 M€</td>
<td>+19 %</td>
</tr>
</tfoot>
</table>
Avec scope en place, le lecteur d'écran annonce « Europe, Chiffre d'affaires, 2,4 M€ » en traversant la ligne : les en-têtes voyagent avec la cellule. C'est tout l'objet de la thématique 5. Pour un tableau complexe (en-têtes fusionnés sur plusieurs niveaux), scope ne sait plus exprimer les relations : il faut donner un id à chaque <th> et lister ces id dans l'attribut headers de chaque cellule, technique détaillée dans le guide Tableaux complexes accessibles.
Le tableau large se gère par un conteneur défilant, jamais en laissant la page entière défiler :
<!-- Les tableaux sont la première cause de défilement horizontal à
320 px. Le conteneur rend le tableau défilant ; tabindex="0" le
rend défilable AU CLAVIER ; le rôle et le nom disent ce qui défile
(critère 10.11). -->
<div role="region" aria-labelledby="ca-caption" tabindex="0"
class="defilement-tableau">
<table>
<caption id="ca-caption">Chiffre d'affaires par région, T3 2026</caption>
...
</table>
</div>
.defilement-tableau { overflow-x: auto; }
.defilement-tableau:focus-visible {
outline: 2px solid #0056b3;
outline-offset: 2px;
}
Et les contre-exemples qui concentrent l'essentiel des non-conformités de la thématique 5 :
<!-- À ne pas faire : un titre au-dessus au lieu d'un caption.
Le <h2> n'est associé à rien : le tableau est annoncé
« tableau, 3 colonnes, 4 lignes », sans titre (critère 5.4). -->
<h2>Chiffre d'affaires par région</h2>
<table>
<tr><th scope="col">Région</th></tr>
</table>
<!-- À ne pas faire : des en-têtes de ligne en <td>.
LE défaut de la thématique 5 : en traversant la ligne, le lecteur
d'écran annonce « 2,4 M€, +12 % »... de quoi ? -->
<tr>
<td>Europe</td>
<td>2,4 M€</td>
</tr>
<!-- À ne pas faire : une cellule d'angle vide dans la ligne d'en-têtes.
La colonne des en-têtes de ligne n'a pas de nom. Si le design
l'exige vide, y placer un texte masqué visuellement. -->
<th scope="col"></th>
<!-- À faire dans ce cas : -->
<th scope="col"><span class="sr-only">Région</span></th>
<!-- À ne pas faire : un tableau de mise en page avec du balisage de
tableau de données (critère 5.8). S'il s'agit vraiment de mise en
page : role="presentation", et mieux, CSS grid. -->
<table>
<caption>Mise en page</caption>
<tr><th>Barre latérale</th><td>Contenu principal</td></tr>
</table>
<!-- À ne pas faire : un conteneur défilant sans tabindex.
Molette et doigt défilent, le clavier jamais : les colonnes de
droite sont inatteignables (critère 10.11). -->
<div style="overflow-x: auto">
<table>...</table>
</div>
Défauts fréquents et impact utilisateur
- En-têtes de ligne en
<td>: le défaut le plus répandu de la thématique 5. En traversant une ligne, le lecteur d'écran annonce « 2,4 M€, +12 % » sans jamais rattacher la région : les en-têtes de colonne seuls font la moitié du travail (critères 5.6 et 5.7). - Un titre au-dessus du tableau au lieu d'un
<caption>: le tableau est annoncé « tableau, 3 colonnes, 4 lignes » sans titre ; dans une page à plusieurs tableaux, impossible de les distinguer sans les parcourir (critère 5.4). <th>sansscopesur un tableau à double entrée : le navigateur devine les associations et se trompe dès que le tableau n'est pas trivial ; les cellules sont annoncées avec les mauvais en-têtes (critère 5.7).scopeconservé sur un tableau complexe à en-têtes fusionnés : les associations sont fausses avec assurance, ce qui est pire qu'absentes ; il fautheaders/id(critère 5.7).- Cellule d'angle vide dans la ligne d'en-têtes : la colonne des en-têtes de ligne n'a pas de nom.
- Conteneur défilant sans
tabindex: l'utilisateur au clavier n'a aucun moyen d'atteindre les colonnes hors écran (critère 10.11).
Ce que les outils automatiques ne détectent pas
- Des en-têtes de ligne balisés
<td>: c'est du HTML parfaitement valide, seule la lecture humaine voit qu'il s'agissait d'en-têtes. - La pertinence du titre (critère 5.5) et celle du résumé d'un tableau complexe (critère 5.2) : un
<caption>vide de sens passe tous les contrôles syntaxiques. - Des associations
headers/idsyntaxiquement correctes mais sémantiquement fausses : la cellule reliée aux mauvais en-têtes ne se voit qu'à la lecture.
La thématique 5 est par ailleurs l'une des mieux couvertes par les outils automatiques, dont notre scanner : <th> sans scope, <caption> mal placé ou éléments de tableau de données dans un tableau de présentation sont détectables. Bonne première passe, qui laisse entiers les trois angles morts ci-dessus.
Vérifier ce composant
Protocole manuel rapide, dans cet ordre :
- Le test des en-têtes de ligne, celui que tout le monde rate : au lecteur d'écran, se placer sur une cellule au milieu du tableau. Elle doit annoncer SES DEUX en-têtes : « Europe, Chiffre d'affaires, 2,4 M€ ». Si seul l'en-tête de colonne est annoncé, les en-têtes de ligne sont des
<td>. - Le test du titre : le tableau doit s'annoncer avec son titre. « Tableau » tout court signifie
<caption>absent ou remplacé par un simple titre au-dessus. - Le test des 320 px (critère 10.11) : réduire la fenêtre à 320 px de large. Si la page entière défile horizontalement, le tableau doit être enveloppé dans un conteneur défilant ; puis vérifier au clavier que Tab atteint ce conteneur et que les flèches le font défiler.
- Balayage automatique en complément, pour les
scopemanquants et les<caption>mal placés.
Deux outils gratuits du site aident à ce contrôle : le Simulateur Lecteur d'Écran montre l'arbre d'accessibilité du tableau (titre, en-têtes de colonnes et de lignes réellement exposés), et l'outil Résoudre un critère RGAA fournit pour chaque critère de la thématique 5 un exemple conforme à copier et le guide associé.
Approfondir avec les fiches critères
- Critère 5.1 : Résumé tableaux complexes
- Critère 5.2 : Pertinence résumé
- Critère 5.3 : Linéarisation tableaux layout
- Critère 5.4 : Titre des tableaux
- Critère 5.5 : Pertinence titre
- Critère 5.6 : En-têtes colonnes/lignes
- Critère 5.7 : Association en-têtes/cellules
- Critère 5.8 : Tableaux de mise en page
- Critère 10.11 : Reflow
Vérifier ce composant sur votre site ?
Le scan repère les défauts détectables automatiquement (rôles incohérents, champs sans étiquette, attributs ARIA orphelins) ; le reste se vérifie à la main avec les protocoles de cette fiche.
Lancer un scan gratuit