RGAA Lab

Composants accessibles

Les titres et la structure

Le niveau d'un titre dit sa place dans le plan du document, jamais la taille voulue à l'écran. Choisir h3 parce que h2 fait trop gros produit un plan qui ne décrit plus la page. Démo, code, critères RGAA.

4 critères RGAA en jeu

Essayez-le

Sur quoi le niveau des titres est-il choisi ?

Préparer un audit

Avant de relever quoi que ce soit, il faut savoir sur quoi porte l'audit : les pages retenues, les navigateurs visés, la version du référentiel.

Constituer l'échantillon

Huit pages au minimum, choisies pour couvrir les gabarits et les parcours du site — pas huit pages qui se ressemblent.

Les étapes, en résumé

  1. Figer l'échantillon et la configuration de test.
  2. Dérouler les 106 critères sur chaque page.
  3. Joindre une capture à chaque non-conformité.

Relever les non-conformités

Un relevé se relit des mois plus tard, par quelqu'un qui n'était pas là : il porte le critère, l'élément visé et la preuve.

Le plan, relu dans le document

Le plan se lit dans le document rendu, une fois la page affichée.

Basculez d’un mode à l’autre, et surveillez l’extrait de gauche : pas un pixel ne bouge. Le plan de droite, lui, est relu dans le document après chaque bascule : il saute un niveau, et il perd un titre — celui qui n’avait aucune taille à choisir, parce qu’il ne s’adresse qu’aux technologies d’assistance.

Les titres de l’extrait commencent à h3 et non à h1 : ils sont réellement dans le plan de la page que vous lisez, sous le titre de section qui les précède. Une démo qui poserait un h1 casserait ici même la règle qu’elle enseigne.

Cette démo existe aussi en page autonome.

L’erreur courante

Le niveau choisi pour la taille qu’il rend.

<!-- À ne pas faire : le niveau suit la police, pas le plan -->
<h1>Préparer un audit</h1>

<h3>Constituer l'échantillon</h3>
<!-- « h2 fait trop gros, h3 tombe juste » -->

<p><strong>Les étapes, en résumé</strong></p>
<!-- pas un titre du tout : il ne devait pas être gros -->

<h6>Relever les non-conformités</h6>

À l’écran, cette page est impeccable. Dans le plan, elle raconte autre chose : un chapitre de niveau 1, une sous-sous-section, une sous-sous-sous-sous-section, et une section entière qui n’existe pas.

Ce que ça coûte se voit au moment où quelqu’un appelle la liste des titres — le sommaire qu’un lecteur d’écran fabrique tout seul, et le premier geste de beaucoup d’utilisateurs sur une page inconnue. Ils y lisent « titre 1, titre 3, titre 6 » sans pouvoir dire ce qui contient quoi, et « Les étapes, en résumé » n’y figure pas : la section qu’il ouvre est introuvable autrement qu’en lisant toute la page, du premier mot au dernier.

Et le strong est le plus grave des trois, parce que c’est le seul que le référentiel refuse sans nuance. Le test 9.1.3 demande que chaque passage de texte constituant un titre soit structuré par une balise hx — ou par role="heading" avec aria-level.

Sur les sauts de niveau, en revanche, la définition officielle de « titre » est plus permissive qu’on ne le croit :

Assurer une stricte hiérarchie entre les titres d’une page web est une bonne pratique, mais la présence de sauts hiérarchiques n’invalide pas le critère tant que cette hiérarchie plus lâche reste cohérente (un titre <h3> peut ainsi venir directement après un titre <h1>, par exemple). La hiérarchie de titres ne doit pas obligatoirement contenir un titre <h1>.

Autrement dit : sauter un niveau est une mauvaise pratique que le référentiel tolère, tant que le plan reste cohérent. Ce qu’il refuse, c’est un plan qui cesse de décrire le document — et c’est exactement ce que produit un niveau choisi pour sa taille, puisque plus rien alors ne relie les deux.

Trois variantes, plus discrètes :

  • Le titre vide, ou réduit à une icône décorative. Il crée un niveau fantôme : le lecteur d’écran annonce « titre de niveau 2 » et s’arrête là.
  • Le h4 posé sur un paragraphe pour l’avoir en gras. Une entrée de plus dans le sommaire, qui n’ouvre aucune section (critère 8.9).
  • Le composant qui fixe son niveau. Un encart réutilisable codé en dur en h2 remonte au rang de section dès qu’on l’insère dans une sous-section.

Le code, pas à pas

1. Le niveau dit la place, la feuille de style dit la taille

<h2 class="titre-discret">Constituer l'échantillon</h2>
.titre-discret {
	font-size: 1rem;
	font-weight: 600;
}

Une balise de titre répond à une question — où suis-je dans le plan ? — et une seule. La taille, la graisse, la couleur répondent à une autre, et c’est la feuille de style qui les tient.

Tant que les deux réponses sortent du même attribut, elles se disputent, et c’est toujours l’œil qui gagne. Séparez-les une fois, et la tentation de descendre d’un niveau pour gagner deux pixels disparaît : il n’y a plus rien à y gagner.

C’est aussi ce que dit le critère 10.9 par l’autre bout. Un texte qui n’est un titre que par sa taille donne son statut par la forme seule — qui ne voit pas la page n’a alors aucun moyen de savoir qu’une section commence.

2. Descendre d’un cran à la fois, remonter librement

<h1>Auditer un site</h1>
	<h2>Préparer</h2>
		<h3>Constituer l'échantillon</h3>
		<h3>Figer la configuration</h3>
	<h2>Relever</h2>

La règle tient en deux mouvements. En descendant, un niveau à la fois : un h2 suivi d’un h4 laisse croire à un h3 disparu. En remontant, autant de crans qu’on veut : passer d’un h3 à un h2 ferme une section et en ouvre une autre, ce que personne ne trouve surprenant.

Sur le h1, le référentiel n’exige rien — la définition citée plus haut le dit en toutes lettres. Un seul h1, qui nomme la page, reste néanmoins la convention la plus répandue, et celle qui rend le plan le plus lisible : c’est une préférence assumée, pas une obligation à faire valoir en audit.

Ce que le critère 9.1 demande vraiment, c’est que la hiérarchie soit pertinente (test 9.1.1) et que chaque titre le soit aussi (test 9.1.2). Le contrôle est donc celui-ci : affichez le plan seul, sans le reste de la page. S’il se lit comme un sommaire, il est bon.

3. Le titre qu’on n’affiche pas

Certaines sections n’ont pas besoin de titre visible : l’œil comprend d’un coup qu’une colonne latérale rassemble des liens connexes, ou qu’une zone liste des résultats. Le plan, lui, n’a rien pour le deviner.

<nav aria-labelledby="titre-connexes">
	<h2 id="titre-connexes" class="sr-only">Sur le même thème</h2>
	<ul></ul>
</nav>
/* Retiré de l'écran, gardé dans le document. */
.sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

La définition officielle valide expressément ce cas : « les titres visuellement cachés via CSS sont considérés comme présents et valident le critère 9.1 ».

Encore faut-il le bon masquage. display: none, visibility: hidden et l’attribut hidden retirent le titre pour tout le monde, technologies d’assistance comprises — c’est ce que la définition de contenu caché énumère. Un titre masqué ainsi ne manque pas seulement à l’écran : il manque au plan.

Un mot de mesure : un titre invisible est utile là où une zone se comprend sans lui, pas partout. Un plan de quarante entrées dont trente ne se voient nulle part n’est plus le sommaire d’un document, c’est une seconde page écrite par en dessous.

4. Le niveau d’un composant vient de la page

Un composant réutilisable ne connaît pas sa profondeur : c’est celui qui l’insère qui la connaît. Le niveau se reçoit donc, comme n’importe quelle autre donnée.

<script>
	let { niveau = 2, titre } = $props();
</script>

<svelte:element this={`h${niveau}`}>{titre}</svelte:element>

C’est aussi le cas des composants de cette collection : les intitulés d’un accordéon sont des titres, et leur niveau suit la section qui les contient — pas l’inverse.

Quand aucune balise hx n’est possible, role="heading" avec aria-level fait un titre à part entière : le référentiel les nomme côte à côte dans tous les tests du critère 9.1. Le cas est rare, et il coûte plus cher à maintenir qu’un hx, l’attribut de niveau pouvant se désynchroniser sans que rien ne le montre.

5. Les régions, l’autre moitié du plan

Les titres disent ce que la page contient. Ils ne disent pas : le menu, le contenu principal, le pied de page. C’est le rôle des régions, et l’objet du critère 9.2 — header, nav, main, footer, avec un seul main visible.

Les deux plans se complètent et ne se remplacent pas : un site dont les titres sont irréprochables mais qui n’a pas de main oblige à retraverser le menu à chaque page. La fiche régions et points de repère traite ce versant en détail.

6. Ce texte est-il vraiment un titre ?

Le dernier contrôle est celui du bon sens, et il coupe dans les deux sens. Un texte qui ouvre une section doit être un titre, même s’il ne paraît pas gros. Un texte qui n’ouvre rien — une accroche, un label, une date en gras — ne doit pas en être un, même s’il paraît gros.

Entre les deux, la question qui tranche : si je ne lisais que ce texte et les autres titres, comprendrais-je ce que contient la page ?

Au clavier

Des titres ne s’actionnent pas : la tabulation ne s’y arrête pas, et c’est normal. Le clavier qui compte ici est celui du lecteur d’écran, et ces raccourcis sont la raison d’être de tout ce qui précède.

ToucheEffet
H (NVDA, JAWS)Va au titre suivant, quel que soit son niveau. Le focus de lecture s’y pose et le titre est annoncé avec son niveau.
1 à 6 (NVDA, JAWS)Va au titre suivant du niveau demandé — ce qui n’a de sens que si les niveaux en ont un.
Inser + F7 (NVDA)Ouvre la liste des éléments, où le plan des titres s’affiche en entier.
Inser + F6 (JAWS)Ouvre la liste des titres de la page.
VO + U (VoiceOver)Ouvre le rotor, dont une entrée est le plan des titres.

Ce que le lecteur d’écran restitue

À la lecture continue, le niveau accompagne le texte : « Préparer un audit, titre de niveau 3 », puis « Constituer l’échantillon, titre de niveau 4 ». Dans la liste des titres, le plan se donne d’un bloc, chaque entrée avec son niveau. La formulation varie d’un lecteur à l’autre ; les informations, non.

Le diagnostic inverse est ici particulièrement simple, parce qu’il n’y a qu’une seule information à entendre.

Si vous entendez l’intitulé sans « titre de niveau », ce n’est pas un titre : c’est un paragraphe en gras, et il n’entrera dans aucun sommaire. Si la liste des titres est vide, la page n’en a aucun, et il ne reste que la lecture linéaire. Si les niveaux annoncés sautent de 3 à 6, ils ont été choisis ailleurs que dans le plan.

Checklist

  • Choisir le niveau d’après le plan, la taille d’après la feuille de style.
  • Descendre d’un niveau à la fois ; remonter autant qu’il faut.
  • Un titre pour chaque section, et son texte décrit ce qu’elle contient.
  • Aucun titre vide, ni réduit à une icône décorative.
  • Masquer un titre par la technique sr-only, jamais par display: none.
  • Un composant réutilisable reçoit son niveau, il ne le fixe pas.
  • Relire le plan seul : il doit se lire comme un sommaire.

Les critères RGAA en jeu

Vérifiez votre composant avec l'extension

Pour aller plus loin

Sources