Le même tableau de factures affiche des intitulés de colonnes, « Date », « Montant », « Statut ». Ces intitulés ne sont pas des valeurs comme les autres : ils servent de repère pour comprendre chaque cellule qui se trouve en dessous, et cette différence doit se voir dans le code, pas seulement à l'écran.
C'est le rôle de la balise <th> : contrairement à <td>, elle annonce explicitement qu'une cellule joue ce rôle de repère.
Définition
th signifie « table header », en-tête de tableau. Elle marque une cellule comme repère pour une ligne ou une colonne entière, et non comme une valeur isolée. Par défaut, la plupart des navigateurs affichent son contenu en gras et centré, une convention visuelle héritée des tout premiers tableaux HTML.
Ce rendu par défaut n'est qu'un effet de bord du style du navigateur : la vraie valeur de th se situe dans le sens qu'elle donne au document, pas dans son apparence. Le gras et le centrage se retirent en une ligne de CSS sans que th perde son rôle.
L'attribut scope : col ou row
Sur un tableau simple, un lecteur d'écran devine souvent correctement quelles cellules sont des en-têtes de colonne et lesquelles sont des en-têtes de ligne. Dès que le tableau se complique, plusieurs en-têtes de ligne, des cellules fusionnées, une double ligne d'intitulés, cette déduction automatique devient peu fiable. L'attribut scope lève l'ambiguïté en la précisant explicitement.
scope="col" indique que la cellule sert d'en-tête pour toute la colonne sous elle. scope="row" indique qu'elle sert d'en-tête pour toute la ligne à sa droite. Deux autres valeurs existent, colgroup et rowgroup, pour un en-tête qui couvre tout un groupe de colonnes, une valeur qui fait directement écho à la balise <colgroup>, ou de lignes plutôt qu'une seule.
<table>
<tr><th scope="col">Mois</th><th scope="col">Formations vendues</th><th scope="col">Chiffre d'affaires</th></tr>
<tr><th scope="row">Juin</th><td>42</td><td>3 780 €</td></tr>
<tr><th scope="row">Juillet</th><td>51</td><td>4 590 €</td></tr>
</table>Sémantique et accessibilité
Avec scope correctement posé, un lecteur d'écran annonce l'intitulé de colonne et l'intitulé de ligne avant chaque valeur : au lieu d'entendre simplement « 3 780 euros », un utilisateur non-voyant entend « Chiffre d'affaires, Juin, 3 780 euros ». Cette annonce répétée à chaque cellule rend un tableau de données long réellement navigable, sans obliger à retenir mentalement la position de chaque colonne.
Un td mis en gras et centré par CSS ressemble visuellement à un th, mais ne porte aucune des informations qui permettent à un lecteur d'écran de l'associer aux cellules qu'il introduit. Remplacer un vrai th par un td stylisé pour « faire pareil » retire toute la valeur d'accessibilité du tableau, même si rien ne change à l'écran pour un utilisateur voyant.
th et td : même position, rôle différent
| Aspect | th | td |
|---|---|---|
| Rôle | En-tête, repère pour d'autres cellules | Valeur ordinaire |
| Rendu par défaut | Gras et centré | Normal, aligné à gauche |
| Lu par un lecteur d'écran | Intitulé annoncé avant chaque valeur associée | Valeur seule, sans intitulé répété |
| Attribut clé | scope | colspan, rowspan |
Bonnes pratiques
Réservez th aux cellules qui jouent vraiment un rôle de repère, la première ligne du tableau le plus souvent, parfois aussi la première colonne. Posez scope dès qu'un tableau dépasse une poignée de lignes ou de colonnes, plutôt que de compter sur la déduction automatique du navigateur. Ne choisissez jamais entre th et td pour une question d'apparence : le gras et le centrage se corrigent en une ligne de CSS, une fois th choisi pour la bonne raison, le sens de la cellule.
Questions fréquentes
Peut-on avoir plusieurs th sur une même ligne ?
Oui, c'est même la situation la plus courante : une ligne d'en-têtes de colonnes est presque toujours composée uniquement de th, un par colonne, suivie ensuite de lignes de données composées de td.
Faut-il toujours écrire scope, même sur un tableau très simple ?
Sur un tableau à une seule ligne d'en-têtes de colonnes, la plupart des lecteurs d'écran devinent correctement la structure même sans scope. Mais l'ajouter ne coûte rien et lève toute ambiguïté, et dès qu'un tableau gagne des en-têtes de ligne ou des cellules fusionnées, scope devient nécessaire plutôt qu'optionnel.
Le style d'un th peut-il être changé sans perdre son sens ?
Oui, entièrement. Le CSS peut retirer le gras, retirer le centrage, aligner le texte à gauche, changer sa couleur : rien de tout cela n'affecte le rôle sémantique de la balise, qui reste attaché à th lui-même et non à son apparence à l'écran.