Cours HTML et CSS · Module 4: Flexbox

L'accessibilité en HTML - Construire pour tout le monde

11 min de lecture
Dans cette leçon8

Bienvenue au Temple du Savoir Universel ! Tout comme les anciens Égyptiens construisaient des pyramides avec de larges escaliers accessibles à tous ceux qui voulaient entrer, nous devons nous aussi construire des pages web accessibles à tous les utilisateurs, y compris les personnes en situation de handicap. Découvre ARIA et le HTML sémantique : les clés pour créer un internet inclusif !

Qu'est-ce que l'accessibilité (A11y) ?

L'accessibilité (abrégée a11y - « a » + 11 lettres + « y ») consiste à faire en sorte que les pages web puissent être utilisées par tout le monde, quelles que soient les capacités physiques ou techniques de chacun.

Qui bénéficie de pages accessibles :

  • Les personnes aveugles et malvoyantes (lecteurs d'écran)
  • Les personnes sourdes et malentendantes (sous-titres, transcriptions)
  • Les personnes ayant des difficultés motrices (navigation au clavier)
  • Les personnes âgées (polices plus grandes, contraste élevé)
  • Les utilisateurs avec une connexion lente (pages légères)

Analogie égyptienne : Tout comme les hiéroglyphes étaient compréhensibles à différents niveaux par les prêtres, les scribes et les gens ordinaires, une page web devrait être accessible à tous les utilisateurs.

Balises sémantiques vs divs avec des rôles

HTML sémantique - La première étape vers l'accessibilité

1<!-- MAUVAIS - des divs sans signification -->
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
9<div class="main-content">
10  <div class="article">
11    <div class="article-title">Titre de l'article</div>
12    <div class="article-text">Contenu de l'article...</div>
13  </div>
14</div>
15
16<!-- BON - des balises sémantiques -->
17<header>
18  <nav>
19    <a href="/">Accueil</a>
20    <a href="/about">À propos</a>
21  </nav>
22</header>
23
24<main>
25  <article>
26    <h1>Titre de l'article</h1>
27    <p>Contenu de l'article...</p>
28  </article>
29</main>

Pourquoi les balises sémantiques sont meilleures :

  • Les lecteurs d'écran reconnaissent automatiquement la structure
  • Les moteurs de recherche indexent mieux le contenu (SEO)
  • Les navigateurs fournissent des comportements par défaut
  • La maintenance du code est plus facile
  • La navigation au clavier fonctionne d'emblée

Les balises sémantiques clés

1<!-- Structure de la page -->
2<header>Logo et navigation principale</header>
3<nav>Menu de navigation</nav>
4<main>Contenu principal de la page (un seul par page !)</main>
5<article>Unité de contenu autonome (article de blog, article)</article>
6<section>Section thématique d'un document</section>
7<aside>Contenu secondaire, lié au contenu principal</aside>
8<footer>Pied de section ou de page</footer>
9
10<!-- Contenu textuel -->
11<h1>, <h2>, <h3>, <h4>, <h5>, <h6>Titres dans la hiérarchie</h1>
12<p>Paragraphe de texte</p>
13<blockquote>Citation</blockquote>
14<figure>Illustration avec légende</figure>
15<figcaption>Légende de l'illustration</figcaption>
16
17<!-- Éléments interactifs -->
18<button>Bouton (pour les actions)</button>
19<a href="#">Lien (pour la navigation)</a>
20<form>Formulaire</form>
21<input>, <select>, <textarea>Champs de formulaire</input>

ARIA - Accessible Rich Internet Applications

ARIA est un ensemble d'attributs qui étendent la sémantique HTML et aident les technologies d'assistance (lecteurs d'écran) à comprendre l'interface.

La règle d'or d'ARIA :

« N'utilise pas ARIA si tu peux utiliser du HTML sémantique ! »

Les rôles ARIA - Définir le rôle d'un élément

Les rôles indiquent au lecteur d'écran ce qu'est un élément donné :

1<!-- Quand le HTML sémantique ne suffit PAS -->
2
3<!-- Sans rôle - on ne sait pas ce que c'est -->
4<div class="navigation">
5  <a href="/">Accueil</a>
6  <a href="/products">Produits</a>
7</div>
8
9<!-- Avec role="navigation" -->
10<div role="navigation">
11  <a href="/">Accueil</a>
12  <a href="/products">Produits</a>
13</div>
14
15<!-- LE MIEUX - balise sémantique (aucun rôle nécessaire !) -->
16<nav>
17  <a href="/">Accueil</a>
18  <a href="/products">Produits</a>
19</nav>

Les rôles ARIA les plus populaires :

1<!-- Navigation -->
2<div role="navigation">Menu</div>
3<!-- Mieux : <nav> -->
4
5<!-- Contenu principal -->
6<div role="main">Contenu principal</div>
7<!-- Mieux : <main> -->
8
9<!-- Bouton -->
10<div role="button" tabindex="0">Cliquer</div>
11<!-- Mieux : <button> -->
12
13<!-- Alerte -->
14<div role="alert">Erreur ! Veuillez remplir tous les champs.</div>
15
16<!-- Bannière (en-tête de page) -->
17<div role="banner">Logo et navigation</div>
18<!-- Mieux : <header> -->
19
20<!-- Informations complémentaires -->
21<div role="complementary">Barre latérale</div>
22<!-- Mieux : <aside> -->
23
24<!-- Contenu d'article -->
25<div role="article">Article de blog</div>
26<!-- Mieux : <article> -->
27
28<!-- Recherche -->
29<div role="search">
30  <form>
31    <input type="search" aria-label="Rechercher sur le site">
32    <button>Rechercher</button>
33  </form>
34</div>
35
36<!-- Panneau d'onglet -->
37<div role="tabpanel" aria-labelledby="tab1">
38  Contenu de l'onglet 1
39</div>

REMARQUE : Si tu utilises un rôle sur une div, tu dois aussi gérer :

  • La navigation au clavier (tabindex)
  • La gestion des événements (Entrée, Espace pour les boutons)
  • Les états (aria-pressed, aria-expanded)

aria-label - Ajouter une étiquette

aria-label ajoute une description textuelle à un élément, qui est lue par les lecteurs d'écran :

1<!-- Icône sans texte -->
2<button aria-label="Fermer la fenêtre">
3  <svg><!-- Icône X --></svg>
4</button>
5
6<!-- Lien vers un réseau social -->
7<a href="https://facebook.com" aria-label="Suis-nous sur Facebook">
8  <img src="fb-icon.svg" alt="">
9</a>
10
11<!-- Barre de recherche -->
12<input
13  type="search"
14  aria-label="Rechercher des produits dans la boutique"
15  placeholder="Rechercher...">
16
17<!-- Bouton de menu hamburger -->
18<button
19  class="hamburger"
20  aria-label="Ouvrir le menu de navigation"
21  aria-expanded="false">
22  <span></span>
23  <span></span>
24  <span></span>
25</button>
26
27<!-- Navigation de pagination -->
28<nav aria-label="Navigation des pages">
29  <a href="?page=1">1</a>
30  <a href="?page=2" aria-current="page">2</a>
31  <a href="?page=3">3</a>
32</nav>

Quand utiliser aria-label :

  • L'élément n'a qu'une icône (pas de texte)
  • Le texte visible est ambigu ou incomplet
  • Le contexte n'est pas évident

Quand NE PAS utiliser aria-label :

  • L'élément a déjà un texte clair et visible
  • Tu peux utiliser <label> dans un formulaire
  • L'image a déjà un alt approprié

aria-labelledby - Lier à une étiquette existante

aria-labelledby relie un élément à un autre élément qui sert d'étiquette :

1<!-- Boîte de dialogue modale -->
2<div role="dialog" aria-labelledby="dialog-title" aria-describedby="dialog-desc">
3  <h2 id="dialog-title">Confirmer la suppression</h2>
4  <p id="dialog-desc">Es-tu sûr de vouloir supprimer cet élément ? Cette action est irréversible.</p>
5  <button>Supprimer</button>
6  <button>Annuler</button>
7</div>
8
9<!-- Onglets -->
10<div role="tablist">
11  <button role="tab" id="tab1" aria-controls="panel1">Description</button>
12  <button role="tab" id="tab2" aria-controls="panel2">Caractéristiques</button>
13</div>
14
15<div role="tabpanel" id="panel1" aria-labelledby="tab1">
16  Description détaillée du produit...
17</div>
18
19<div role="tabpanel" id="panel2" aria-labelledby="tab2">
20  Caractéristiques techniques...
21</div>
22
23<!-- Section avec titre -->
24<section aria-labelledby="section-heading">
25  <h2 id="section-heading">Derniers articles</h2>
26  <article>...</article>
27  <article>...</article>
28</section>

aria-describedby - Description supplémentaire

aria-describedby ajoute une description étendue à un élément :

1<!-- Champ de formulaire avec aide -->
2<label for="password">Mot de passe</label>
3<input
4  type="password"
5  id="password"
6  aria-describedby="password-requirements">
7<p id="password-requirements">
8  Le mot de passe doit contenir au moins 8 caractères, dont une majuscule et un chiffre.
9</p>
10
11<!-- Bouton avec contexte supplémentaire -->
12<button aria-describedby="delete-warning">
13  Supprimer le compte
14</button>
15<p id="delete-warning">
16  Cette action est irréversible et supprimera toutes tes données.
17</p>
18
19<!-- Infobulle -->
20<button aria-describedby="tooltip1">
21  Enregistrer
22</button>
23<span id="tooltip1" role="tooltip" hidden>
24  Enregistrer les modifications du document (Ctrl+S)
25</span>

L'importance de l'attribut alt sur les images

L'attribut alt est l'un des plus importants éléments d'accessibilité. Il décrit une image pour les personnes qui ne peuvent pas la voir.

Bonnes pratiques pour alt

1<!-- BON - alt descriptif -->
2<img
3  src="pyramids-giza.jpg"
4  alt="Trois pyramides de Gizeh au coucher du soleil, avec des chameaux au premier plan">
5
6<!-- BON - alt fonctionnel pour un lien -->
7<a href="/products">
8  <img src="shop-icon.svg" alt="Aller à la boutique">
9</a>
10
11<!-- BON - alt vide pour les images décoratives -->
12<img src="decorative-line.svg" alt="">
13
14<!-- MAUVAIS - alt identique au nom du fichier -->
15<img src="img_001.jpg" alt="img_001">
16
17<!-- MAUVAIS - « photo », « image » inutiles -->
18<img src="cat.jpg" alt="Photo montrant un chat">
19<!-- Mieux : alt="Chat endormi sur un canapé" -->
20
21<!-- MAUVAIS - alt manquant -->
22<img src="important-chart.jpg">
23<!-- Le lecteur d'écran lira le nom du fichier ! -->

Règles pour écrire un bon texte alt :

  1. Décris le contenu, pas la forme (« Chat endormi » au lieu de « Photo »)
  2. Le contexte compte - qu'est-ce que l'image apporte au contenu ?
  3. Sois concis - 125-150 caractères maximum
  4. Images décoratives - utilise un alt="" vide
  5. Images de texte - transcris le texte exactement
  6. Diagrammes complexes - utilise aussi aria-describedby ou <figcaption>
1<!-- Image décorative (un arrière-plan CSS serait préférable) -->
2<img src="divider.svg" alt="">
3
4<!-- Image avec texte -->
5<img src="sale-banner.jpg" alt="Soldes -50 % - aujourd'hui seulement !">
6
7<!-- Graphique complexe -->
8<figure>
9  <img
10    src="sales-chart.jpg"
11    alt="Graphique des ventes 2024"
12    aria-describedby="chart-description">
13  <figcaption id="chart-description">
14    Le graphique montre une croissance des ventes de 10 000 en janvier à 50 000 en décembre 2024.
15    Le plus grand bond a eu lieu en novembre, pendant le Black Friday.
16  </figcaption>
17</figure>

Exemple : composant accessible vs inaccessible

Bouton inaccessible

1<div class="button" onclick="submitForm()">
2  <img src="send-icon.svg">
3</div>
4
5<style>
6.button {
7  background: blue;
8  padding: 10px;
9  cursor: pointer;
10}
11</style>

Problèmes :

  • Pas de sémantique (div au lieu de button)
  • Ne fonctionne pas au clavier (Tab, Entrée)
  • Pas de description textuelle (seulement une icône)
  • Le lecteur d'écran ne sait pas que c'est un bouton

Bouton accessible

1<button
2  type="submit"
3  aria-label="Envoyer le formulaire">
4  <img src="send-icon.svg" alt="">
5</button>
6
7<style>
8button {
9  background: blue;
10  padding: 10px;
11  cursor: pointer;
12  border: none;
13  color: white;
14}
15
16button:focus {
17  outline: 3px solid orange;
18  outline-offset: 2px;
19}
20</style>

Avantages :

  • <button> sémantique - prise en charge automatique du clavier
  • aria-label décrit la fonction
  • Contour de focus pour les utilisateurs au clavier
  • type="submit" - fonction claire

Comment tester l'accessibilité

1. Lighthouse (Chrome DevTools)

Étape par étape :

  1. Ouvre DevTools (F12)
  2. Onglet « Lighthouse »
  3. Coche « Accessibility »
  4. Clique sur « Generate report »

Lighthouse va vérifier :

  • Le contraste des couleurs
  • Les attributs alt sur les images
  • Les attributs ARIA
  • La hiérarchie des titres
  • Les étiquettes de formulaire
  • Et bien plus encore...

Résultat : Un rapport avec une note de 0 à 100 et des problèmes précis à corriger.

2. Navigation au clavier

Test manuel :

  1. Range la souris
  2. Utilise uniquement le clavier :
    • Tab - passer à l'élément suivant
    • Maj+Tab - revenir au précédent
    • Entrée - activer un lien/bouton
    • Espace - cocher une case, activer un bouton
    • Flèches - naviguer dans un select, des boutons radio
  3. Vérifie :
    • Vois-tu le contour de focus ?
    • L'ordre est-il logique ?
    • Peux-tu atteindre tout ?
    • N'y a-t-il pas de « pièges à focus » ?

3. Lecteur d'écran

Windows : NVDA (gratuit) Mac : VoiceOver (intégré - Cmd+F5) Chrome : ChromeVox (extension)

Commandes de base (NVDA) :

  • Ctrl - arrêter la lecture
  • Insert+Flèche bas - tout lire
  • H - aller au titre suivant
  • K - aller au lien suivant
  • B - aller au bouton suivant
  • F - aller au champ de formulaire suivant

4. axe DevTools (extension)

Une extension Chrome/Firefox qui détecte automatiquement les problèmes d'accessibilité :

  • Installation : Chrome Web Store -> « axe DevTools »
  • Utilisation : F12 -> onglet « axe DevTools » -> « Scan ALL »

5. WAVE (WebAIM)

Outil en ligne : https://wave.webaim.org/

  • Saisis l'URL de la page
  • Tu recevras une analyse visuelle avec les erreurs signalées

Liste de contrôle d'accessibilité

HTML et sémantique :

  • J'utilise des balises sémantiques (<header>, <nav>, <main>, <article>)
  • La hiérarchie des titres est logique (h1 -> h2 -> h3)
  • Chaque page a exactement un <main>

Images :

  • Toutes les images ont un attribut alt
  • Les images décoratives ont un alt="" vide
  • Les textes alt sont descriptifs et concis

Formulaires :

  • Chaque champ a un <label> ou un aria-label
  • Les erreurs de validation sont claires et lisibles
  • Les champs obligatoires sont marqués (required ou aria-required="true")

Navigation au clavier :

  • Je peux tout atteindre en utilisant uniquement Tab
  • Le contour de focus est visible
  • L'ordre de tabulation est logique
  • Les éléments interactifs répondent à Entrée/Espace

Couleurs et contraste :

  • Le contraste du texte est d'au moins 4.5:1 (texte normal)
  • Le contraste du texte est d'au moins 3:1 (grand texte 18px+)
  • L'information n'est pas transmise UNIQUEMENT par la couleur

ARIA :

  • ARIA n'est utilisé que lorsque le HTML sémantique ne suffit pas
  • Les attributs role sont utilisés correctement
  • Le contenu dynamique a aria-live
  • Les modales ont role="dialog" et aria-labelledby

Tests :

  • Lighthouse Accessibility : 90+
  • Testé avec un lecteur d'écran
  • Testé au clavier uniquement

Récapitulatif

HTML sémantique :

  • Utilise <button>, <nav>, <main>, <article> au lieu de divs
  • Offre une accessibilité automatique
  • Mieux pour le SEO et la maintenance

Rôles ARIA :

  • role="navigation", role="main", role="button"
  • À utiliser UNIQUEMENT lorsque le HTML sémantique ne suffit pas
  • Nécessite une gestion supplémentaire du clavier et des états

Étiquettes ARIA :

  • aria-label - ajoute une description textuelle
  • aria-labelledby - lie à un élément existant
  • aria-describedby - ajoute une description étendue

Alt sur les images :

  • Décris le contenu, pas la forme
  • alt="" vide pour les décorations
  • Le contexte compte

Tests :

  • Lighthouse (DevTools)
  • Navigation au clavier
  • Lecteur d'écran (NVDA, VoiceOver)
  • axe DevTools
  • WAVE

N'oublie pas : L'accessibilité n'est pas une fonctionnalité en plus : c'est une partie fondamentale de la construction de pages web. Tout comme les pyramides de Gizeh ont été bâties pour toutes les générations, les pages web devraient être accessibles à tous les utilisateurs !

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. Quelle est la règle d’or d’ARIA décrite dans la leçon ?

  2. 2. Quand est-il préférable d’utiliser l’attribut aria-label ?

Voici 2 des 3 questions de cette leçon. Réponds aux autres dans le jeu.

Tâches pratiques dans le jeu

  • Tri vertical

    Range les balises sémantiques d’une structure de page typique, de haut en bas :

Articles utiles