En-têtes de tableau manquants : pourquoi un tableau de données a besoin de th, pas de gras
La mise en forme visuelle peut distinguer les en-têtes d'un tableau. Les lecteurs d'écran, eux, ont besoin d'une association exploitable par programme entre en-têtes et cellules de données pour annoncer le contexte pertinent au fil du parcours. Employez un balisage d'en-tête et des associations adaptés à la structure du tableau.
Cela relève du critère de succès 1.3.1 des WCAG (Information et relations), niveau A.
La correction pour un tableau simple
Utilisez <th> pour les cellules d'en-tête plutôt qu'un <td> mis en forme, et définissez scope pour indiquer si l'en-tête s'applique à sa colonne ou à sa ligne :
<!-- Avant : les en-têtes ne sont que du texte en gras -->
<table>
<tr><td><b>Client</b></td><td><b>Chiffre d'affaires</b></td></tr>
<tr><td>Société Acme</td><td>1,2 M€</td></tr>
</table>
<!-- Après : de vraies cellules d'en-tête, explicitement portées -->
<table>
<thead>
<tr><th scope="col">Client</th><th scope="col">Chiffre d'affaires</th></tr>
</thead>
<tbody>
<tr><td>Société Acme</td><td>1,2 M€</td></tr>
</tbody>
</table>
Un lecteur d'écran peut désormais annoncer « Chiffre d'affaires : 1,2 M€ » en arrivant sur cette cellule, au lieu du seul « 1,2 M€ » : c'est l'association scope="col" qui fournit automatiquement le nom de la colonne.
Les tableaux complexes exigent un appariement explicite id/headers
Le simple scope ne suffit plus pour les tableaux à en-têtes multiniveaux ou irréguliers (un tableau comportant à la fois des en-têtes de ligne et de colonne, ou des cellules d'en-tête fusionnées sur plusieurs colonnes). Dans ce cas, chaque <th> reçoit un id unique, et chaque cellule de données énumère les identifiants d'en-tête qui la concernent via l'attribut headers :
<table>
<tr>
<th id="t1">T1</th>
<th id="t2">T2</th>
</tr>
<tr>
<th id="ca">Chiffre d'affaires</th>
<td headers="ca t1">1,2 M€</td>
<td headers="ca t2">1,4 M€</td>
</tr>
</table>
C'est plus verbeux, mais c'est le seul moyen fiable de lever l'ambiguïté sur le sens d'une cellule dans un tableau réellement multidimensionnel.
La première chose à vérifier : s'agit-il seulement d'un tableau de données ?
Les tableaux utilisés uniquement pour la mise en page (pratique courante sur les sites anciens, et dans certains HTML générés automatiquement ou exportés depuis un courriel) ne doivent pas recevoir d'éléments <th> : cela annoncerait à tort des cellules de mise en page comme des en-têtes de données. Si un tableau n'a aucune relation logique entre lignes et colonnes à communiquer, la meilleure correction consiste généralement à le remplacer intégralement par un balisage non tabulaire sémantique (des div avec CSS Grid ou Flexbox), plutôt qu'à greffer un balisage d'en-tête sur ce qui n'a jamais été de véritables données tabulaires.
Références officielles
- Deque University : table-fake-caption
- Deque University : td-has-header
- Technique W3C H43
- Technique W3C H51
- Technique W3C H63
- Technique W3C H73
Questions fréquentes
- Pourquoi le texte en gras ne suffit-il pas comme en-tête de tableau ?
- Le gras ou une trame de fond ne sont que des indices visuels. Un lecteur d'écran qui parcourt les cellules une à une a besoin d'un véritable balisage `<th>` pour annoncer l'en-tête auquel se rattache une cellule de données ; la mise en forme seule ne lui transmet rien.
- Comment baliser correctement les en-têtes de tableau ?
- Utilisez `<th>` pour les cellules d'en-tête et ajoutez `scope=col` ou `scope=row` afin d'associer chaque cellule de données au bon en-tête. Pour les tableaux complexes, reliez les cellules au moyen de `headers` et `id`.
- Cela s'applique-t-il aux tableaux de mise en page ?
- Non : il s'agit des tableaux de données. Les tableaux utilisés uniquement pour la mise en page doivent être remplacés par du CSS et n'ont jamais besoin de `<th>` ; l'exigence vise les tableaux qui présentent de véritables données tabulaires.
Articles liés
Vous souhaitez connaître le score de votre propre site ?
Lancer un test d'accessibilité gratuit