Le bouton qui n'en était pas un
Dans la leçon 1, Marie ne pouvait pas valider son panier. Le « bouton » de la page était un <div> avec un onclick. À la souris, ça marchait. Au clavier et au lecteur d'écran, ça n'existait pas.
Voici pourquoi, en détail. Un <div> est une boîte neutre. Il n'a aucun rôle : le lecteur d'écran ne l'annonce pas comme un bouton. Il n'est pas focusable : la touche Tab passe à côté. Il n'a aucun comportement clavier : Entrée et Espace ne déclenchent rien. Un onclick ne réagit qu'à la souris.
Le <button> natif, lui, donne tout ça gratuitement. Tu écris une balise, et le navigateur t'offre le rôle, le focus, le clavier et l'état désactivé. Sans une ligne de JavaScript en plus.
| Ce que tu obtiens | <div onclick> | <button> |
|---|---|---|
| Rôle annoncé (« bouton ») | ❌ aucun | ✅ natif |
| Focusable au clavier (Tab) | ❌ non | ✅ oui |
| Activation Entrée | ❌ non | ✅ oui |
| Activation Espace | ❌ non | ✅ oui |
État désactivé (disabled) | ❌ à coder | ✅ natif |
Cinq cadeaux, une seule balise. Reconstruire tout ça à la main sur un <div> prend des dizaines de lignes, et tu en oublieras toujours une. Le natif ne se trompe jamais.
La règle qui résume 80 % de l'accessibilité
L'élément natif d'abord. Avant d'inventer un composant, demande-toi quelle balise HTML fait déjà le travail. Un bouton, c'est <button>. Un lien, c'est <a href>. Une case à cocher, c'est <input type="checkbox">. Le natif arrive avec son rôle, son focus et son clavier intégrés. Tu ne les recodes pas, tu les hérites.
Reste un piège classique : confondre bouton et lien. Visuellement, on peut les rendre identiques. Pour l'accessibilité, ce sont deux choses différentes.
- Un lien (
<a href>) navigue. Il emmène l'utilisateur ailleurs : une autre page, une autre section. Le lecteur d'écran l'annonce « lien », et l'utilisateur sait qu'il va se déplacer. - Un bouton (
<button>) agit. Il déclenche une action sur place : valider, ouvrir un menu, ajouter au panier. Le lecteur d'écran l'annonce « bouton », et l'utilisateur sait que quelque chose va se passer ici.
Le lecteur d'écran les annonce différemment, et l'utilisateur en attend des comportements différents. Un lien qui agit, ou un bouton qui navigue, c'est une promesse trahie. « Valider le panier » est une action : c'est un bouton. « Voir mes commandes » est une navigation : c'est un lien.
Les landmarks : le GPS du lecteur d'écran
Tu connais déjà <header>, <nav>, <main>, <footer> côté structure. On les revisite ici par l'angle accessibilité. Ces balises créent des landmarks : des repères dans l'arbre d'accessibilité.
Pourquoi ça compte ? Un voyant lit la page de haut en bas, mais saute des yeux ce qui ne l'intéresse pas. Un utilisateur de lecteur d'écran ne voit rien : il navigue par landmarks et par titres. C'est son Ctrl+F. Il appuie sur une touche et saute directement à la navigation, ou au contenu principal, ou au pied de page.
<header>: l'en-tête de la page (logo, titre du site).<nav>: un bloc de navigation. Annoncé « navigation ».<main>: le contenu principal, unique sur la page.<aside>: un contenu de côté (encart, liens connexes).<footer>: le pied de page.
Une page sans <main> n'a pas de raccourci « aller au contenu ». Le lecteur d'écran propose un saut direct vers le contenu principal, à condition qu'un <main> existe. Sans lui, l'utilisateur doit re-traverser tout l'en-tête et le menu à chaque page. Sur un site de dix pages, c'est dix fois le même menu réécouté avant d'arriver au vrai contenu.
Les titres : le sommaire que personne ne voit
L'autre grand outil de navigation, c'est la liste des titres. Le lecteur d'écran peut afficher tous les <h1> à <h6> d'une page comme un sommaire, et l'utilisateur saute de l'un à l'autre. Cette liste est le plan de ta page.
Deux règles simples gardent ce plan lisible.
- Un seul
<h1>par page : le titre du contenu, le sommet du plan. - Pas de saut de niveau. Après un
<h2>vient un<h3>, pas un<h4>. Sauter de<h2>à<h4>laisse un trou dans le plan : l'utilisateur se demande quelle section il a ratée.
Le piège : beaucoup de gens choisissent un niveau de titre pour sa taille. « Je veux du petit, je mets <h4>. » Non. Le niveau dit la place dans la hiérarchie, pas la taille. La taille, c'est le CSS. Choisis le bon niveau, puis stylise-le.
Le labo ci-dessous contient une mini-page truffée de problèmes d'accessibilité, mais qui s'affiche très bien à l'écran. Combien de problèmes vas-tu trouver ? Cherche d'abord, puis compare.
Voir la réponse
Il y en a 5, et aucun ne se voit à l'œil. Un faux bouton en <div>, une navigation en <div>, l'absence de <main>, un saut de titre <h1> vers <h3>, et un faux lien en <span>. Le rendu est parfait ; l'arbre d'accessibilité, lui, est cassé. C'est tout le piège de l'accessibilité : ce qui manque ne se voit pas. Ouvre le détail complet sous le labo après avoir cherché.
Ce que le lecteur d'écran « voit »
À gauche, la page découpée en landmarks. À droite, la liste des titres comme un sommaire. Ce sont les deux cartes que le lecteur d'écran utilise pour se déplacer, sans jamais voir un seul pixel.
À toi : trouve et corrige les 5 problèmes
Voici une mini-page de boutique. Elle s'affiche parfaitement, mais elle cache 5 problèmes d'accessibilité. Édite le code à gauche, corrige-les avec ce que tu viens d'apprendre, et clique sur Exécuter pour voir le rendu. Le visuel ne changera presque pas : c'est normal, l'accessibilité se joue dans la structure, pas dans les pixels.
Voir les 5 problèmes et les corrections
- Navigation en
<div class="nav">→ remplace par<nav>. Le lecteur d'écran l'annoncera comme un landmark « navigation », et l'utilisateur pourra y sauter directement. - Pas de
<main>→ enveloppe le contenu principal (titre, produit, bouton) dans<main>. Sans lui, pas de raccourci « aller au contenu ». - Saut de titre
<h1>→<h3>→ le nom du modèle doit être un<h2>. Le niveau dit la place dans le plan, pas la taille. - Faux bouton
<div class="btn" onclick>→<button onclick="acheter()">Ajouter au panier</button>. Rôle, focus et clavier deviennent natifs. - Faux lien
<span class="link" onclick>→ « Voir les conditions de vente » est une navigation :<a href="/cgv">. Un vrai lien, focusable et activable au clavier.
Le code corrigé :
<nav>
<a href="#">Accueil</a>
<a href="#">Boutique</a>
</nav>
<main>
<h1>Chaussures de course</h1>
<h2>Modèle Sprint 200</h2>
<p>Légère, respirante, idéale route.</p>
<button onclick="acheter()">Ajouter au panier</button>
<p>
<a href="/cgv">Voir les conditions de vente</a>
</p>
</main>
The button that wasn't one
In lesson 1, Marie couldn't check out her cart. The page's "button" was a <div> with an onclick. With a mouse, it worked. For the keyboard and the screen reader, it didn't exist.
Here's why, in detail. A <div> is a neutral box. It has no role: the screen reader doesn't announce it as a button. It is not focusable: the Tab key skips right past it. It has no keyboard behaviour: Enter and Space trigger nothing. An onclick only reacts to the mouse.
The native <button>, on the other hand, gives all of that for free. You write one tag, and the browser hands you the role, the focus, the keyboard and the disabled state. Without a single extra line of JavaScript.
| What you get | <div onclick> | <button> |
|---|---|---|
| Announced role ("button") | ❌ none | ✅ native |
| Keyboard-focusable (Tab) | ❌ no | ✅ yes |
| Enter activation | ❌ no | ✅ yes |
| Space activation | ❌ no | ✅ yes |
Disabled state (disabled) | ❌ to code | ✅ native |
Five gifts, one tag. Rebuilding all of that by hand on a <div> takes dozens of lines, and you'll always forget one. The native element never gets it wrong.
The rule that sums up 80% of accessibility
Native element first. Before inventing a component, ask which HTML tag already does the job. A button is <button>. A link is <a href>. A checkbox is <input type="checkbox">. The native element arrives with its role, focus and keyboard built in. You don't recode them, you inherit them.
One classic trap remains: confusing a button with a link. Visually, you can make them identical. For accessibility, they are two different things.
- A link (
<a href>) navigates. It takes the user elsewhere: another page, another section. The screen reader announces it as "link", and the user knows they're about to move. - A button (
<button>) acts. It triggers an action right here: submit, open a menu, add to cart. The screen reader announces it as "button", and the user knows something is about to happen on this spot.
The screen reader announces them differently, and the user expects different behaviours. A link that acts, or a button that navigates, is a broken promise. "Check out the cart" is an action: it's a button. "View my orders" is navigation: it's a link.
Landmarks: the screen reader's GPS
You already know <header>, <nav>, <main>, <footer> from the structure angle. We revisit them here through the accessibility lens. These tags create landmarks: reference points in the accessibility tree.
Why does it matter? A sighted person reads the page top to bottom but skips with their eyes whatever doesn't interest them. A screen reader user sees nothing: they navigate by landmarks and headings. It's their Ctrl+F. They press a key and jump straight to the navigation, or the main content, or the footer.
<header>: the page header (logo, site title).<nav>: a navigation block. Announced as "navigation".<main>: the main content, unique on the page.<aside>: side content (callout, related links).<footer>: the page footer.
A page with no <main> has no "skip to content" shortcut. The screen reader offers a direct jump to the main content, provided a <main> exists. Without it, the user has to wade back through the whole header and menu on every page. On a ten-page site, that's the same menu heard ten times before reaching the real content.
Headings: the table of contents nobody sees
The other big navigation tool is the heading list. The screen reader can show every <h1> to <h6> on a page as a table of contents, and the user jumps from one to the next. That list is your page's outline.
Two simple rules keep that outline readable.
- One single
<h1>per page: the content's title, the top of the outline. - No level skipping. After an
<h2>comes an<h3>, not an<h4>. Jumping from<h2>to<h4>leaves a hole in the outline: the user wonders which section they missed.
The trap: many people pick a heading level for its size. "I want it small, I'll use <h4>." No. The level says the place in the hierarchy, not the size. Size is CSS. Pick the right level, then style it.
The lab below holds a mini-page riddled with accessibility problems, yet it displays perfectly on screen. How many problems will you find? Look first, then compare.
Show the answer
There are 5, and none of them are visible to the eye. A fake button in a <div>, a navigation in a <div>, the missing <main>, a heading jump from <h1> to <h3>, and a fake link in a <span>. The rendering is perfect; the accessibility tree is broken. That's the whole trap of accessibility: what's missing doesn't show. Open the full breakdown under the lab once you've searched.
What the screen reader "sees"
On the left, the page split into landmarks. On the right, the heading list as a table of contents. These are the two maps the screen reader uses to move around, without ever seeing a single pixel.
Your turn: find and fix the 5 problems
Here's a mini shop page. It displays perfectly, but it hides 5 accessibility problems. Edit the code on the left, fix them with what you just learned, and click Run to see the result. The visuals will barely change: that's expected, accessibility plays out in the structure, not in the pixels.
Show the 5 problems and the fixes
- Navigation in
<div class="nav">→ replace with<nav>. The screen reader will announce it as a "navigation" landmark, and the user can jump straight to it. - No
<main>→ wrap the main content (title, product, button) in<main>. Without it, no "skip to content" shortcut. - Heading jump
<h1>→<h3>→ the model name should be an<h2>. The level says the place in the outline, not the size. - Fake button
<div class="btn" onclick>→<button onclick="buy()">Add to cart</button>. Role, focus and keyboard become native. - Fake link
<span class="link" onclick>→ "See terms of sale" is navigation:<a href="/terms">. A real link, focusable and keyboard-activable.
The fixed code:
<nav>
<a href="#">Home</a>
<a href="#">Shop</a>
</nav>
<main>
<h1>Running shoes</h1>
<h2>Sprint 200 model</h2>
<p>Light, breathable, ideal for the road.</p>
<button onclick="buy()">Add to cart</button>
<p>
<a href="/terms">See terms of sale</a>
</p>
</main>
🎯 Pratique
S'entraîner (clique pour ouvrir) :
💬 Ré-explique sans regarder
Explique à un collègue pourquoi un <button> est meilleur qu'un <div onclick> pour l'accessibilité. Cite au moins trois choses que le natif donne gratuitement.
<div> est une boîte neutre, sans rôle, non focusable, sans clavier. Le <button> natif donne gratuitement (1) le rôle « bouton » annoncé par le lecteur d'écran, (2) le focus au clavier via Tab, (3) l'activation par Entrée ET Espace, (4) l'état désactivé. La règle d'or : l'élément natif d'abord, on hérite au lieu de recoder.🧠 Rappel libre
Sans remonter : par quoi un utilisateur de lecteur d'écran navigue-t-il dans une page, et que perd-il si la page n'a pas de <main> ?
<main>, il perd le raccourci « aller au contenu » et doit re-traverser tout l'en-tête et le menu à chaque page.⚖️ Juge le code de l'IA
Tu demandes à l'IA une carte produit cliquable. Elle livre : <div class="card" onclick="ouvrir()">…</div> et commente : « J'ai pris un <div>, c'est plus flexible pour le style qu'un <button>. » Tu acceptes, ou tu rejettes ?
<button> se stylise entièrement en CSS (un reset de quelques lignes suffit). En choisissant un <div onclick>, l'IA sacrifie le rôle, le focus et le clavier natifs : la carte devient invisible au lecteur d'écran et inutilisable sans souris. Le bon code : <button> (ou <a href> si la carte navigue vers une page produit). Le style n'est jamais une raison d'abandonner le natif.<h2> à <h4>. Quel est le problème ?keydown sur Entrée à son faux bouton <div>. Au test, Entrée fonctionne, mais Espace ne fait toujours rien. Pourquoi ?Native gives you the keyboard for free. But you still need to SEE where you are. Lesson 3: Tab, visible focus, and the 30-second test almost nobody does.
Lesson 3: Keyboard and visible focus →