Tableau de mise en forme
Un tableau de mise en forme est un élément HTML <table> détourné de sa fonction d'origine pour disposer visuellement des éléments sur la page. Il ne contient aucune relation logique entre lignes et colonnes. Pour éviter que les lecteurs d'écran ne l'annoncent comme un vrai tableau, il doit porter l'attribut role="presentation" ou role="none" et ne contenir aucune balise sémantique de tableau de données (<th>, <caption>, scope).
Un lecteur d'écran rencontre une balise <table>. Il annonce : « tableau, 3 lignes, 2 colonnes ». L'utilisateur s'attend à des données structurées avec des en-têtes. Sauf que ce <table> ne contient aucune donnée tabulaire. Il servait uniquement à aligner deux blocs de texte côte à côte. Bienvenue dans le problème des tableaux de mise en forme.
#Pourquoi ça pose problème
Avant CSS, les développeurs utilisaient <table> pour contrôler la disposition visuelle des pages. Cette pratique a largement reculé, mais on la retrouve encore dans les e-mails HTML, les CMS anciens et le code hérité.
Le problème : un lecteur d'écran traite toute <table> comme un tableau de données. Il annonce le nombre de lignes et de colonnes, propose un mode de navigation par cellules, et tente de relier les cellules à des en-têtes. Quand il n'y a pas d'en-têtes, l'utilisateur navigue à l'aveugle dans une grille qui n'a aucun sens logique.
Le RGAA traite ce sujet dans sa thématique 5 (critères 5.3 et 5.8) : un tableau de mise en forme ne doit pas utiliser de balisage propre aux tableaux de données, et son contenu doit rester compréhensible une fois linéarisé.
#Comment neutraliser la sémantique
La solution tient en un attribut :
<table role="presentation">
<tr>
<td>Colonne gauche</td>
<td>Colonne droite</td>
</tr>
</table>role="presentation" indique aux technologies d'assistance d'ignorer la sémantique tabulaire. Le contenu des cellules reste accessible, mais le conteneur n'est plus annoncé comme un tableau. Depuis ARIA 1.1, role="none" est un synonyme exact — il a été ajouté parce que le mot « presentation » prêtait à confusion.
Attention à ne pas confondre avec aria-hidden="true". Ce dernier masque le contenu entier (texte compris) de l'arbre d'accessibilité. role="presentation" ne masque que la sémantique du conteneur : les cellules <td> et leur texte restent lisibles. Scott O'Hara détaille bien cette distinction.
#Les erreurs que personne ne vous signale
La plus fréquente : ajouter role="presentation" mais laisser des <th> ou un <caption> dans le tableau. D'après la technique F92 du W3C, appliquer role="presentation" à un tableau contenant du balisage sémantique de données est un échec du critère 1.3.1 des WCAG.
L'autre piège : le contenu linéarisé perd son sens. Un lecteur d'écran lit les cellules dans l'ordre du code source, de gauche à droite, ligne par ligne. Si vous avez placé un titre dans la deuxième colonne et son contenu dans la première, la lecture sera incohérente.
#En résumé
Si votre <table> ne contient pas de données tabulaires, ajoutez role="presentation", supprimez tout balisage de tableau de données (<th>, <caption>, scope, headers), et vérifiez que le contenu reste lisible une fois linéarisé. La meilleure solution reste de ne pas utiliser <table> du tout — CSS Flexbox et Grid font le même travail sans polluer l'arbre d'accessibilité.