Accéder au contenu principalAccéder à la navigationAccéder au pied de page
Page d'accueil IncluddyPage d'accueil Includdy
  • FAQ
  • Blog
  • Contact
Includdy

Rendons le web accessible à tous

Produit

  • Scan automatique
  • Correction guidée
  • Collaboration

Ressources

  • FAQ
  • Blog
  • Glossaire
  • RGAA
  • Plan du site

Légal

  • CGU
  • CGV
  • Mentions légales
  • Politique de confidentialité

© 2026 Includdy. Tous droits réservés.

  1. Accueil
  2. RGAA 4.1.2
  3. Tableaux
  4. 5.6 En-têtes de tableau

Pour chaque tableau de données, chaque en-tête de colonne et chaque en-tête de ligne sont-ils correctement déclarés ?

Un utilisateur de lecteur d’écran navigue dans un tableau cellule par cellule. À chaque déplacement, il entend la valeur de la cellule — et, si les en-têtes sont correctement structurés, son contexte. Sans <th>, le lecteur annonce « 42 ». Avec un en-tête déclaré, il annonce « Ventes, Trimestre 2 : 42 ». La donnée est là, mais muette.

Pour que les technologies d’assistance reconnaissent un en-tête, il doit être déclaré de façon programmatique. Pour les en-têtes couvrant l’intégralité d’une colonne ou d’une ligne, vous avez deux options : un élément <th> ou un attribut WAI-ARIA role="columnheader" / role="rowheader". Pour les en-têtes partiels — ceux qui ne couvrent qu’une portion de ligne ou de colonne — seul <th> est accepté par le RGAA.

Ce critère vérifie uniquement la déclaration des en-têtes. L’association explicite entre en-têtes et cellules de données dans les tableaux complexes est l’objet du critère 5.7.

4 tests pour vérifier la présence d'en-têtes dans les tableaux de données

1️⃣ En-têtes de colonnes via <th> ou role="columnheader"

  1. Repérez tous les tableaux de données dans la page (excluez les tableaux de mise en page).
  2. Pour chaque cellule qui fait office d’en-tête sur toute une colonne, inspectez son balisage.
  3. Vérifiez qu’il s’agit :
    • d’un élément <th>, ou
    • d’un élément quelconque portant l’attribut role="columnheader".
  4. Un seul en-tête de colonne codé avec <td> suffit à faire échouer le test. Si tous les en-têtes de colonnes complètes respectent la condition, le test est validé.

2️⃣ En-têtes de lignes via <th> ou role="rowheader"

  1. Repérez tous les tableaux de données dans la page.
  2. Identifiez les en-têtes de lignes : typiquement la première cellule de chaque ligne, qui nomme la catégorie (région, produit, personne, etc.).
  3. Pour chaque en-tête couvrant toute une ligne, vérifiez qu’il utilise :
    • un élément <th>, ou
    • un élément portant l’attribut role="rowheader".
  4. Si tous les en-têtes de lignes complètes respectent cette condition, le test est validé.

3️⃣ En-têtes partiels via élément <th>

  1. Repérez tous les tableaux de données dans la page.
  2. Identifiez les en-têtes partiels : ceux qui ne couvrent qu’une partie d’une ligne ou d’une colonne (courant dans les tableaux à en-têtes groupés ou fusionnés sur plusieurs niveaux).
  3. Pour chacun, vérifiez qu’il utilise un élément <th>.
  4. Attention : role="columnheader" et role="rowheader" ne sont pas valides ici. Seul <th> est accepté pour les en-têtes partiels.
  5. Si tous les en-têtes partiels sont des <th>, le test est validé.

4️⃣ Cellules multi-en-têtes via <td> ou <th>

  1. Repérez tous les tableaux de données dans la page.
  2. Identifiez les cellules associées à plusieurs en-têtes simultanément (par exemple, une cellule de données à l’intersection d’un en-tête de ligne et de plusieurs en-têtes de colonnes imbriqués).
  3. Vérifiez que chacune de ces cellules est codée avec une balise <td> ou <th> standard.
  4. Si toutes ces cellules utilisent <td> ou <th>, le test est validé. En pratique, si votre tableau est en HTML natif, ce test est quasi automatiquement satisfait.

Exemples

❌ Non conforme : En-têtes visuels sans sémantique HTML

<table>
  <tr>
    <td><strong>Produit</strong></td>
    <td><strong>Prix HT</strong></td>
    <td><strong>Stock</strong></td>
  </tr>
  <tr>
    <td>Clavier mécanique</td>
    <td>79 €</td>
    <td>14</td>
  </tr>
  <tr>
    <td>Souris ergonomique</td>
    <td>45 €</td>
    <td>32</td>
  </tr>
</table>

Les cellules « Produit », « Prix HT » et « Stock » sont visuellement distinctes grâce au <strong>, mais elles restent des <td> pour les technologies d’assistance. NVDA ou VoiceOver ne les reconnaîtra pas comme en-têtes : en naviguant vers la cellule « 79 € », l’utilisateur entend simplement « 79 € » sans savoir de quel produit ni de quelle colonne il s’agit.

✅ Conforme : En-têtes de colonnes et de lignes correctement structurés

<table>
  <caption>Inventaire du matériel informatique</caption>
  <thead>
    <tr>
      <th scope="col">Produit</th>
      <th scope="col">Prix HT</th>
      <th scope="col">Stock</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Clavier mécanique</th>
      <td>79 €</td>
      <td>14</td>
    </tr>
    <tr>
      <th scope="row">Souris ergonomique</th>
      <td>45 €</td>
      <td>32</td>
    </tr>
  </tbody>
</table>

Les en-têtes de colonnes utilisent <th scope="col"> et les en-têtes de lignes <th scope="row">. En naviguant vers la cellule « 79 € », le lecteur d’écran annonce « Prix HT, Clavier mécanique : 79 € ». L’utilisateur comprend la donnée sans revenir en haut du tableau ni parcourir la ligne depuis le début.

✅ Conforme : En-têtes déclarés avec ARIA sur un tableau en <div>

<div role="table" aria-label="Planning hebdomadaire de l'équipe">
  <div role="row">
    <span role="columnheader">Membre</span>
    <span role="columnheader">Lundi</span>
    <span role="columnheader">Mardi</span>
  </div>
  <div role="row">
    <span role="rowheader">Alice Dupont</span>
    <span role="cell">Présente</span>
    <span role="cell">Télétravail</span>
  </div>
</div>

Quand le tableau est construit avec des <div> et <span> (fréquent avec les frameworks front-end), les rôles ARIA role="columnheader" et role="rowheader" permettent de déclarer les en-têtes de façon programmatique. Cette approche est valide pour les en-têtes couvrant toute la colonne ou toute la ligne. Pour un tableau en HTML natif, préférez toujours <th> : plus court, plus robuste, mieux supporté.

Astuces et pièges

⚠️ Le <td> mis en gras ou coloré ne compte pas

C’est l’erreur numéro un en audit de tableaux. Des dizaines de tableaux utilisent <td style="font-weight: bold"> ou <td class="table-header"> pour simuler visuellement un en-tête. Le style CSS ne crée aucune sémantique : les lecteurs d’écran ignorent l’apparence et se fient uniquement au balisage HTML. Seul <th> ou un rôle ARIA explicite produisent un en-tête programmatique.

⚠️ Les en-têtes de lignes, les oubliés du RGAA

Les développeurs pensent aux en-têtes de colonnes (première ligne) et oublient systématiquement les en-têtes de lignes (première colonne). Dans un tableau listant des régions, des produits ou des personnes, la première cellule de chaque ligne est un en-tête : elle doit être un <th scope="row">. Sans cela, le test 5.6.2 échoue, même si toute la première ligne est correcte.

💡 role="columnheader" n’est pas un substitut universel au <th>

Les rôles ARIA columnheader et rowheader ne couvrent que les en-têtes s’appliquant à l’intégralité d’une colonne ou d’une ligne (tests 5.6.1 et 5.6.2). Pour les en-têtes partiels (test 5.6.3), seul <th> est accepté. Ajouter role="columnheader" sur un en-tête partiel semble satisfaire le critère visuellement, mais ne sera pas conforme au RGAA.

⚠️ Tableaux multi-niveaux : le critère 5.6 n’est qu’un point de départ

Un tableau avec des en-têtes fusionnés sur plusieurs rangées (<th colspan="3"> suivi de sous-en-têtes) peut valider le critère 5.6 si tous ces en-têtes sont des <th>. Mais sans attributs scope, id et headers, les cellules de données ne seront pas correctement associées à leurs en-têtes. C’est le critère 5.7 qui impose ces associations explicites pour les tableaux complexes.

⚠️ Test 5.6.4 : une formulation ambiguë dans le RGAA officiel

La méthodologie du test 5.6.4 contient une erreur de rédaction reconnue : l’étape 3 est une copie de celle du test précédent. En pratique, ce test vérifie uniquement que les cellules associées à plusieurs en-têtes utilisent <td> ou <th> — et non des éléments non sémantiques. Pour tout tableau en HTML natif, cette condition est mécaniquement remplie dès lors que le tableau est codé avec les balises standard.

Questions fréquentes

Quand utiliser role="columnheader" plutôt que <th> pour satisfaire le critère RGAA 5.6 ?

Oui, pour les en-têtes couvrant toute une colonne ou toute une ligne. Le RGAA accepte les deux : <th> et un élément avec role="columnheader". En pratique, si vous écrivez du HTML natif, utilisez toujours <th> : c’est plus court, plus robuste, et mieux supporté par les lecteurs d’écran. Réservez les rôles ARIA aux situations où vous n’avez pas la main sur le balisage (composant tiers, framework générant des <div>).

Quelle est la différence entre les critères RGAA 5.6 et 5.7 pour les tableaux ?

Le critère 5.6 vérifie que les en-têtes existent et sont déclarés (<th> ou rôle ARIA). Le critère 5.7 vérifie qu’ils sont correctement associés aux cellules de données via les attributs scope, id et headers. Un tableau peut valider le 5.6 (tous les en-têtes sont des <th>) et échouer au 5.7 (les associations sont absentes ou incorrectes pour un tableau complexe). Pour un tableau simple à un seul niveau d’en-têtes, les deux critères sont généralement satisfaits ensemble.

Comment repérer rapidement les problèmes d'en-têtes de tableau lors d'un audit RGAA ?

Ouvrez les DevTools, cliquez sur chaque cellule qui ressemble visuellement à un en-tête, et vérifiez dans le panneau Éléments si c’est un <th> ou un <td>. Includdy signale automatiquement les <td> utilisés comme en-têtes. En pratique : si le <thead> est absent ou si la première ligne du tableau utilise des <td>, le critère 5.6 échoue presque certainement.

Quel impact ont <th colspan> et <th rowspan> sur la conformité au critère RGAA 5.6 ?

Oui. Le RGAA ne pose aucune restriction sur colspan ou rowspan pour ce critère. Un <th colspan="3">Trimestre 1</th> couvrant trois colonnes est un en-tête valide au sens du 5.6. L’association de cet en-tête aux cellules qu’il couvre est traitée par le critère 5.7.

Quand l'attribut scope est-il obligatoire pour satisfaire le critère RGAA 5.6 ?

Non. Le critère 5.6 n’exige pas l’attribut scope. La présence de <th> suffit pour valider les tests 5.6.1 à 5.6.4. L’attribut scope est requis par le critère 5.7. Cela dit, ajouter scope="col" et scope="row" dès le départ est une bonne habitude : cela prépare le tableau à satisfaire les deux critères sans double travail.

Références

RGAA 4.1.2 : Critère 5.6
WCAG 2.1 :1.3.1 (A)H51F911.3.1 (A)
Critère suivant5.7 : Association cellules / en-têtesCritère précédent5.5 : Pertinence du titre de tableau
1.Images
2.Cadres
3.Couleurs
4.Multimédia
5.Tableaux
5.15.25.35.45.55.65.75.8
6.Liens
7.Scripts
8.Éléments obligatoires
9.Structuration de l’information
10.Présentation de l’information
11.Formulaires
12.Navigation
13.Consultation