Cours HTML et CSS · Module 10: Accessibilité (a11y)

Le HTML sémantique et l'accessibilité

8 min de lecture
Dans cette leçon7

Imagine un pèlerin aveugle qui entre dans un temple où aucune salle ne porte d'inscription au-dessus de son entrée. Il entend l'écho de ses pas, mais il ne sait pas s'il se trouve dans la salle de prière ou dans une réserve. C'est exactement ce que ressent l'utilisateur d'un lecteur d'écran sur une page construite uniquement avec des <div>. Dans l'Égypte antique, les hiéroglyphes avaient des significations strictement définies - chaque symbole remplissait une fonction précise. Il en va de même avec le HTML sémantique : chaque balise porte une information sur le rôle et le sens du contenu, ce qui est crucial pour les technologies d'assistance.

Pourquoi la sémantique est-elle si importante ?

Les lecteurs d'écran (screen readers) ne « voient » pas la page - ils lisent sa structure HTML. Lorsque tu utilises <div> pour tout, le lecteur ne sait pas ce qui est de la navigation, ce qui est un titre et ce qui est le contenu principal. Compare deux versions du même fragment de la page du musée - d'abord la « soupe de div », puis la version sémantique :

1<!-- MAUVAIS - "soupe de div" -->
2<div class="header">
3    <div class="nav">
4        <div class="nav-item">Accueil</div>
5        <div class="nav-item">À propos</div>
6    </div>
7</div>
8<div class="content">
9    <div class="title">Bienvenue au musée</div>
10    <div class="text">Description de l'exposition...</div>
11</div>
12
13<!-- BON - HTML sémantique -->
14<header>
15    <nav aria-label="Navigation principale">
16        <ul>
17            <li><a href="/">Accueil</a></li>
18            <li><a href="/about">À propos</a></li>
19        </ul>
20    </nav>
21</header>
22<main>
23    <h1>Bienvenue au musée</h1>
24    <p>Description de l'exposition...</p>
25</main>

Les deux versions peuvent avoir exactement le même aspect, car le CSS sait faire ressembler un <div> à n'importe quoi. La différence est invisible à l'œil, mais énorme pour le lecteur d'écran : dans la seconde version, il annonce une navigation contenant une liste de deux liens, et l'utilisateur peut sauter directement au contenu principal d'un seul raccourci clavier. Le contenu n'a pas changé - seules les balises ont changé, et les simples libellés du menu sont devenus de vrais liens.

Les principales balises sémantiques

Les éléments de sectionnement

Voici sept balises avec lesquelles tu construiras le squelette de presque n'importe quelle page. Traite-les comme des inscriptions au-dessus des entrées des salles - chacune dit ce qui se trouve à l'intérieur :

1<header>  <!-- En-tête de page ou de section -->
2<nav>     <!-- Navigation -->
3<main>    <!-- Contenu principal de la page (un seul par page !) -->
4<article> <!-- Contenu autonome (billet, article) -->
5<section> <!-- Groupe de contenu thématique -->
6<aside>   <!-- Contenu complémentaire (barre latérale) -->
7<footer>  <!-- Pied de page ou de section -->

Remarque le commentaire à côté de <main> : une page contient exactement un élément <main> visible (la spécification HTML n'en autorise d'autres que s'ils sont masqués avec l'attribut hidden). Il en va autrement de <header> et de <footer> : ils peuvent apparaître plusieurs fois, par exemple à l'intérieur de chaque <article>.

La hiérarchie des titres

Les titres créent la structure du document. Les lecteurs d'écran permettent de naviguer par titres (dans le lecteur NVDA, la touche H mène au titre suivant), si bien que beaucoup d'utilisateurs « parcourent » d'abord une page uniquement par ses titres, comme un pèlerin qui ne lirait que les tablettes au-dessus des salles. C'est pourquoi leur hiérarchie doit être correcte :

1<!-- MAUVAIS - le niveau h2 a été sauté -->
2<h1>Musée égyptien</h1>
3<h3>Expositions permanentes</h3>     <!-- Devrait être h2 ! -->
4<h4>Trésors des pharaons</h4>        <!-- Devrait être h3 ! -->
5
6<!-- BON - hiérarchie correcte -->
7<h1>Musée égyptien</h1>
8<h2>Expositions permanentes</h2>
9<h3>Trésors des pharaons</h3>
10<h3>Momies royales</h3>
11<h2>Expositions temporaires</h2>
12<h3>L'or de Toutânkhamon</h3>

Le niveau d'un titre indique sa place dans la hiérarchie, pas la taille des lettres. Si un <h2> te semble trop grand, réduis-le en CSS, mais ne saute pas à <h3> - le lecteur d'écran en conclurait qu'il manque un niveau dans le document. L'ordre est toujours le même : de <h1> (le titre de la page), en passant par <h2> et <h3>, jusqu'à <h6>.

Les listes

Les listes portent elles aussi du sens. Quand les liens de navigation se trouvent dans une <ul>, le lecteur annonce le nombre d'éléments avant même que l'utilisateur commence à les écouter. La liste de définitions <dl>, quant à elle, associe un terme (<dt>) à son explication (<dd>), comme le dictionnaire d'un scribe :

1<!-- Navigation sous forme de liste - le lecteur annoncera "liste, 4 éléments" -->
2<nav>
3    <ul>
4        <li><a href="/">Accueil</a></li>
5        <li><a href="/exhibitions">Expositions</a></li>
6        <li><a href="/tickets">Billets</a></li>
7        <li><a href="/contact">Contact</a></li>
8    </ul>
9</nav>
10
11<!-- Liste de définitions -->
12<dl>
13    <dt>Scarabée</dt>
14    <dd>Coléoptère sacré symbolisant la renaissance</dd>
15    <dt>Ânkh</dt>
16    <dd>Symbole de la vie éternelle</dd>
17</dl>

Les puces à côté des liens disparaîtront avec une seule règle CSS - l'apparence est l'affaire de la feuille de style, le sens est l'affaire du HTML.

Les rôles de point de repère (landmark roles)

Les balises HTML sémantiques créent automatiquement ce que l'on appelle des landmarks (points de repère), grâce auxquels les utilisateurs de lecteurs d'écran peuvent naviguer rapidement :

Balise HTMLRôle de landmarkDescription
<header>bannerEn-tête de page
<nav>navigationNavigation
<main>mainContenu principal
<aside>complementaryContenu complémentaire
<footer>contentinfoPied de page
<section>region*Section thématique
<form>form*Formulaire

*Nécessite un attribut aria-label ou aria-labelledby.

Le tableau montre aussi l'ordre typique des landmarks depuis le haut de la page : banner, navigation, main, complementary et contentinfo. Il y a toutefois une nuance : <header> et <footer> ne reçoivent les rôles banner et contentinfo que lorsqu'ils ne sont pas imbriqués dans un <article>, un <aside>, un <main>, un <nav> ou une <section>. Ces rôles sont intégrés, alors n'ajoute pas role="navigation" à un <nav> - ce serait répéter la même information.

Exemple pratique

Réunissons tout dans une seule page de musée. Lis le code de haut en bas et essaie de repérer chaque landmark du tableau ci-dessus :

1<!DOCTYPE html>
2<html lang="fr">
3<head>
4    <meta charset="UTF-8">
5    <title>Musée de l'Égypte antique</title>
6</head>
7<body>
8    <header>
9        <h1>Musée de l'Égypte antique</h1>
10        <nav aria-label="Navigation principale">
11            <ul>
12                <li><a href="/">Accueil</a></li>
13                <li><a href="/exhibitions">Expositions</a></li>
14            </ul>
15        </nav>
16    </header>
17
18    <main>
19        <article>
20            <h2>Exposition : Les trésors de Toutânkhamon</h2>
21            <p>Découvre des artefacts incroyables...</p>
22            <figure>
23                <img src="mask.jpg" alt="Masque funéraire en or de Toutânkhamon">
24                <figcaption>Masque funéraire de Toutânkhamon, vers 1323 av. J.-C.</figcaption>
25            </figure>
26        </article>
27    </main>
28
29    <aside aria-label="Informations complémentaires">
30        <h2>Horaires d'ouverture</h2>
31        <p>Lun-Ven : 9h00-17h00</p>
32    </aside>
33
34    <footer>
35        <p>Musée de l'Égypte antique 2024</p>
36    </footer>
37</body>
38</html>

Il n'y a pas un seul <div> ici, et pourtant rien ne manque. L'élément <aside> a reçu un aria-label, donc le lecteur le présentera comme « Informations complémentaires », et la <figure> avec sa <figcaption> relie la photo du masque à sa légende.

Les erreurs sémantiques courantes

Pour finir, voici trois pièges dans lesquels tombe presque chaque débutant. Chaque paire montre d'abord la version erronée, puis la version correcte :

1<!-- MAUVAIS : div à la place d'un button -->
2<div onclick="submit()">Envoyer</div>
3
4<!-- BON : button natif -->
5<button onclick="submit()">Envoyer</button>
6
7<!-- MAUVAIS : span en guise de titre -->
8<span class="big-text">Titre important</span>
9
10<!-- BON : véritable titre -->
11<h2>Titre important</h2>
12
13<!-- MAUVAIS : br pour créer des espacements -->
14<br><br><br>
15
16<!-- BON : margin/padding en CSS -->
17<p style="margin-top: 2rem;">Texte avec espacement</p>

Un <div> avec onclick ne recevra pas le focus au clavier et ne réagira ni à Entrée ni à Espace, alors qu'un <button> natif fait tout cela tout seul. Un <span> qui se fait passer pour un titre n'apparaîtra pas dans la liste des titres du lecteur, et une série de <br> n'est pour lui qu'une suite de lignes vides, pas un espacement. Remarque qu'aucune des versions correctes n'a besoin du moindre attribut ARIA. Mon conseil : avant de sortir un <div>, demande-toi si le HTML n'a pas déjà un élément qui porte ce sens - c'est presque toujours le cas, et c'est lui le meilleur choix.

Valider la sémantique

Tu peux vérifier la sémantique de ta page à l'aide de :

  • W3C Validator - vérifie la validité du HTML
  • WAVE - analyse l'accessibilité de la page
  • Lighthouse - audit d'accessibilité dans Chrome DevTools

Tu les découvriras plus en détail dans la leçon sur les tests d'accessibilité, et dans les prochaines leçons, ce squelette sémantique deviendra la base de la navigation au clavier.

Le HTML sémantique est le fondement de l'accessibilité - tout comme des fondations solides permettent à une pyramide de traverser les millénaires, une sémantique correcte garantit que la page sera accessible à tous les utilisateurs. Chaque élément HTML doit correspondre à son rôle : un titre doit être un titre, une navigation une navigation, et un bouton un bouton.

Pratique

Dans l'éditeur ci-dessous, tu trouveras une page de musée sémantique. Remplace l'une des balises par un <div> et réfléchis à l'information que le lecteur d'écran vient de perdre :

Code de cette leçon : index.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6    <title>Musée de l'Égypte antique - HTML sémantique</title>
7    <link rel="stylesheet" href="style.css">
8</head>
9<body>
10    <header>
11        <h1>Musée de l'Égypte antique</h1>
12        <nav aria-label="Navigation principale">
13            <ul>
14                <li><a href="#exhibitions">Expositions</a></li>
15                <li><a href="#artifacts">Artefacts</a></li>
16                <li><a href="#visit">Rends-nous visite</a></li>
17            </ul>
18        </nav>
19    </header>
20
21    <main>
22        <section id="exhibitions" aria-labelledby="ex-title">
23            <h2 id="ex-title">Expositions actuelles</h2>
24
25            <article>
26                <h3>Les trésors de Toutânkhamon</h3>
27                <p>Découvre des artefacts extraordinaires provenant de la tombe du jeune pharaon,
28                   découverte par Howard Carter en 1922.</p>
29                <figure>
30                    <img src="https://placehold.co/400x250/d4af37/1a1a2e?text=Mask+Tutankhamun"
31                         alt="Masque funéraire en or du pharaon Toutânkhamon">
32                    <figcaption>Masque funéraire de Toutânkhamon, vers 1323 av. J.-C.</figcaption>
33                </figure>
34            </article>
35
36            <article>
37                <h3>Les momies royales</h3>
38                <p>Découvre les secrets de la momification dans l'Égypte antique.</p>
39            </article>
40        </section>
41
42        <section id="artifacts" aria-labelledby="art-title">
43            <h2 id="art-title">Collection d'artefacts</h2>
44            <dl>
45                <dt>Scarabée</dt>
46                <dd>Coléoptère sacré symbolisant la renaissance et la création</dd>
47                <dt>Ânkh</dt>
48                <dd>Symbole de la vie éternelle, porté par les pharaons</dd>
49                <dt>Œil d'Horus</dt>
50                <dd>Symbole de protection, de santé et de pouvoir royal</dd>
51            </dl>
52        </section>
53    </main>
54
55    <aside aria-label="Informations complémentaires">
56        <h2>Horaires d'ouverture</h2>
57        <p>Lun-Ven : 9h00-17h00</p>
58        <p>Sam-Dim : 10h00-18h00</p>
59    </aside>
60
61    <footer>
62        <p>Musée de l'Égypte antique &copy; 2024</p>
63        <nav aria-label="Liens du pied de page">
64            <ul>
65                <li><a href="/privacy">Politique de confidentialité</a></li>
66                <li><a href="/accessibility">Déclaration d'accessibilité</a></li>
67            </ul>
68        </nav>
69    </footer>
70</body>
71</html>

Souviens-toi : une balise sémantique, c'est l'inscription au-dessus de l'entrée d'une salle - grâce à elle, chaque visiteur sait où mène le couloir, même s'il ne voit pas les murs.

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. Combien d'éléments <main> une même page HTML peut-elle contenir ?

  2. 2. Pourquoi une hiérarchie de titres correcte (h1-h6) est-elle importante pour l'accessibilité ?

Tâches pratiques dans le jeu

  • Éditeur de code

    Remplace les div par des balises HTML sémantiques : header, nav (avec aria-label), main, article, aside et footer.

  • Tri vertical

    Range les titres HTML du plus important au moins important :

Articles utiles