Si vous utilisez <div> pour tout — le conteneur de la page, la navigation, le conteneur d'article, la barre latérale — vous n'êtes pas seul. C'était le réflexe par défaut pendant des années. Mais HTML dispose d'éléments sémantiques appropriés depuis HTML5, et les utiliser rend votre code plus lisible, meilleur pour le SEO et véritablement plus accessible. Voyons les éléments qui comptent vraiment.
Le mot « sémantique » signifie simplement que l'élément porte un sens au-delà de sa présentation visuelle. Un <div> ne signifie rien — c'est un bloc générique. Un <nav> indique au navigateur, aux moteurs de recherche et aux technologies d'assistance : « ceci contient des liens de navigation. » Ce contexte ne coûte rien à ajouter et rapporte de multiples façons.
Pourquoi la sémantique est importante
Trois avantages concrets, pas théoriques :
- SEO. Les moteurs de recherche utilisent la structure du document pour comprendre la hiérarchie du contenu. Un élément
<main>signale le contenu principal. Un<article>à l'intérieur signale un contenu autonome. Google utilise ces signaux pour classer les pages. - Accessibilité. Les lecteurs d'écran exposent les régions repères aux utilisateurs. Avec
<nav>,<main>et<aside>en place, les utilisateurs clavier peuvent accéder directement à la section souhaitée — sans parcourir chaque lien de la page. - Maintenabilité. Un nouveau développeur qui lit votre template comprend instantanément la structure de la page.
<header>/<main>/<footer>se documente lui-même d'une façon que<div class="top">/<div class="content">/<div class="bottom">ne fait pas.
Les éléments de mise en page fondamentaux
Ces cinq éléments constituent le squelette extérieur de la plupart des pages. Utilisez-les sur chaque page et vous avez déjà remporté la moitié de la bataille sémantique :
<body>
<header>
<a href="/" class="logo">MyBlog</a>
<nav>
<ul>
<li><a href="/articles">Articles</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
</header>
<main>
<!-- Primary page content goes here -->
</main>
<aside>
<!-- Sidebar: related links, ads, author bio -->
</aside>
<footer>
<p>© 2026 MyBlog. All rights reserved.</p>
</footer>
</body><header>. Contenu d'introduction pour la page ou une section. Contient généralement le logo, le titre du site et la navigation principale. Vous pouvez aussi l'utiliser à l'intérieur d'un<article>pour le bloc de titre propre à l'article.<nav>. Un ensemble de liens de navigation. Tous les groupes de liens n'ont pas besoin d'un<nav>— réservez-le aux blocs de navigation principaux comme la nav du site ou la pagination.<main>. Le contenu dominant de la page. Il ne doit y avoir qu'un seul<main>par page, et il ne doit pas contenir d'éléments répétés d'une page à l'autre (en-tête, nav, pied de page).<aside>. Contenu indirectement lié au contenu principal. Barres latérales, encadrés, articles connexes. Les lecteurs d'écran l'exposent comme un repère complémentaire.<footer>. Pied de page pour la page ou une section. Peut contenir des informations de copyright, une nav secondaire, des liens de contact ou une courte note d'auteur.
<header> et <footer> ne sont pas réservés au niveau de la page. Chaque <article> ou <section> peut avoir son propre <header> et <footer>. C'est particulièrement utile pour les signatures d'articles de blog et les métadonnées au niveau de l'article.article vs section — Quand utiliser chacun
C'est là que les gens se trompent le plus souvent. La règle empirique qui fonctionne vraiment : si le contenu aurait du sens s'il était syndiqué seul (par exemple, publié comme entrée RSS ou partagé sur un autre site), c'est un <article>. S'il n'a de sens que dans le cadre d'un tout plus grand, c'est une <section>.
<!-- article: self-contained, could stand alone -->
<article>
<header>
<h2>Understanding HTTP/2 Push</h2>
<p>By Alice Chen — <time datetime="2026-03-15">March 15, 2026</time></p>
</header>
<p>HTTP/2 Server Push lets the server send resources...</p>
<footer>
<p>Tagged: <a href="/tags/http">HTTP</a>, <a href="/tags/performance">Performance</a></p>
</footer>
</article>
<!-- section: thematic grouping within a page -->
<section>
<h2>Related Articles</h2>
<ul>
<li><a href="/http3-quic">HTTP/3 and QUIC Explained</a></li>
<li><a href="/cdn-strategy">CDN Strategy for Global Apps</a></li>
</ul>
</section>Une <section> doit toujours avoir un titre (<h2> à <h6>). Si votre section n'a pas de titre, c'est généralement le signe que vous devriez utiliser un <div> à la place. La spécification WHATWG est claire à ce sujet : <section> est destiné aux regroupements thématiques, pas aux divisions de mise en page arbitraires.
figure, figcaption, time et address
Quatre éléments que les développeurs oublient souvent mais utilisent régulièrement :
<!-- figure + figcaption: images, code blocks, diagrams, charts -->
<figure>
<img src="/images/latency-chart.png" alt="P99 latency over 24 hours showing a spike at 14:30">
<figcaption>Figure 1: API latency during the Tuesday incident (UTC).</figcaption>
</figure>
<!-- A code block as a figure (totally valid) -->
<figure>
<pre><code>const result = await db.query('SELECT * FROM users WHERE active = true');</code></pre>
<figcaption>Listing 1: Basic active user query.</figcaption>
</figure>
<!-- time: machine-readable dates and times -->
<p>Published <time datetime="2026-04-16T09:00:00Z">April 16, 2026</time></p>
<p>Sale ends in <time datetime="PT2H30M">2 hours 30 minutes</time></p>
<!-- address: contact info for nearest article or body ancestor -->
<address>
Written by <a href="mailto:[email protected]">Alice Chen</a>.<br>
123 Dev Street, San Francisco, CA.
</address><figure>. Tout contenu autonome référencé depuis le flux principal — images, listes de code, graphiques, vidéos. L'essentiel : il pourrait être déplacé en annexe sans perturber la lecture.<figcaption>. La légende d'un<figure>. Doit être le premier ou le dernier enfant de<figure>. Crée une association sémantique entre la légende et le contenu qu'un<p>sous une image n'offre pas.<time>. Dates lisibles par les humains avec un attributdatetimelisible par les machines. La valeurdatetimeutilise le format ISO 8601. Les moteurs de recherche l'utilisent pour le balisage des événements et les signaux de fraîcheur.<address>. Coordonnées pour l'ancêtre<article>le plus proche (ou tout le<body>). Ce n'est pas un élément d'adresse générique — il est spécifiquement destiné aux coordonnées de l'auteur du contenu ou du propriétaire du site.
L'anti-pattern « divitis »
La « divitis » désigne ce qui se produit quand chaque élément de votre HTML est un <div>. Voici un avant/après concret qui illustre le problème :
<!-- Before: divitis -->
<div class="page">
<div class="header">
<div class="brand">TechBlog</div>
<div class="nav">
<div class="nav-item"><a href="/posts">Posts</a></div>
</div>
</div>
<div class="post">
<div class="post-title">Why TypeScript Is Worth It</div>
<div class="post-meta">By Bob — Jan 2026</div>
<div class="post-body">TypeScript adds static types to JavaScript...</div>
</div>
</div>
<!-- After: semantic HTML -->
<body>
<header>
<span class="brand">TechBlog</span>
<nav>
<a href="/posts">Posts</a>
</nav>
</header>
<main>
<article>
<header>
<h1>Why TypeScript Is Worth It</h1>
<p>By Bob — <time datetime="2026-01-10">January 10, 2026</time></p>
</header>
<p>TypeScript adds static types to JavaScript...</p>
</article>
</main>
</body>La version sémantique est en réalité plus courte, nécessite moins de noms de classes CSS, et donne aux navigateurs et aux outils d'assistance tout ce dont ils ont besoin pour comprendre la structure de la page. Vous pouvez toujours tout styler exactement de la même façon avec CSS — les éléments sémantiques n'imposent aucune contrainte visuelle.
Les rôles ARIA — En dernier recours, pas en premier
Les rôles ARIA permettent d'ajouter un sens sémantique aux éléments qui n'en ont pas nativement. Le problème, c'est que les développeurs se tournent souvent vers ARIA là où un élément HTML sémantique ferait mieux le travail. La première règle d'ARIA : n'utilisez pas ARIA si vous pouvez utiliser du HTML natif.
<!-- Wrong: using ARIA where native HTML works -->
<div role="navigation">
<a href="/home">Home</a>
</div>
<!-- Right: just use the semantic element -->
<nav>
<a href="/home">Home</a>
</nav>
<!-- ARIA is appropriate here: custom widget with no HTML equivalent -->
<div
role="tablist"
aria-label="Code examples"
>
<button role="tab" aria-selected="true" aria-controls="panel-js">JavaScript</button>
<button role="tab" aria-selected="false" aria-controls="panel-py">Python</button>
</div>Utilisez ARIA pour les widgets interactifs que le HTML natif ne couvre pas — panneaux à onglets, comboboxes, arborescences, sélecteurs de date. Pour les repères structurels comme la navigation, les en-têtes et le contenu principal, appuyez-vous systématiquement sur les éléments natifs.
Structure complète d'une page d'article de blog
Voici à quoi ressemble une page d'article de blog entièrement sémantique. C'est le pattern utilisé sur les sites qui obtiennent de bons scores dans les audits d'accessibilité sans effort supplémentaire :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Why TypeScript Is Worth It — TechBlog</title>
</head>
<body>
<header>
<a href="/" class="logo">TechBlog</a>
<nav aria-label="Site navigation">
<ul>
<li><a href="/posts">Posts</a></li>
<li><a href="/topics">Topics</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>
<main>
<article>
<header>
<h1>Why TypeScript Is Worth It</h1>
<address>
By <a rel="author" href="/authors/bob">Bob Martinez</a>
</address>
<p>Published <time datetime="2026-01-10">January 10, 2026</time></p>
</header>
<section>
<h2>The Setup Cost Is Real but Front-Loaded</h2>
<p>TypeScript adds a compilation step and requires type annotations...</p>
<figure>
<pre><code>interface User {
id: number;
name: string;
email: string;
}</code></pre>
<figcaption>Listing 1: A typed User interface catches shape errors at compile time.</figcaption>
</figure>
</section>
<section>
<h2>Where TypeScript Pays Off</h2>
<p>The ROI kicks in as team size and codebase complexity grows...</p>
</section>
<footer>
<p>
Tagged: <a href="/tags/typescript">TypeScript</a>,
<a href="/tags/javascript">JavaScript</a>
</p>
</footer>
</article>
<aside aria-label="Related articles">
<h2>You Might Also Like</h2>
<ul>
<li><a href="/ts-vs-js">TypeScript vs JavaScript — A Practical Comparison</a></li>
<li><a href="/ts-generics">TypeScript Generics Explained</a></li>
</ul>
</aside>
</main>
<footer>
<nav aria-label="Footer navigation">
<a href="/privacy">Privacy</a>
<a href="/terms">Terms</a>
</nav>
<p><small>© 2026 TechBlog</small></p>
</footer>
</body>
</html>Remarquez la double utilisation de <header> et <footer> — une fois au niveau de la page, une fois à l'intérieur de <article>. C'est intentionnel et correct. Notez également deux éléments <nav> avec des valeurs aria-label distinctes — cela empêche les lecteurs d'écran de lister deux régions de « navigation » identiques.
Référence rapide : outils utiles
Si vous travaillez avec du HTML et souhaitez nettoyer ou valider votre balisage, le Formateur HTML mettra votre code en forme, et le Validateur HTML détectera les erreurs structurelles comme les balises non fermées et les attributs requis manquants. Pour un audit d'accessibilité plus approfondi, web.dev/accessibility propose d'excellents diagnostics et explications.
Conclusion
Le HTML sémantique ne consiste pas à suivre des règles pour le principe — il s'agit d'écrire du code qui communique clairement aux navigateurs, aux moteurs de recherche, aux outils d'assistance et au prochain développeur qui lira votre template. Les éléments fondamentaux sont simples : <header>, <nav>, <main>, <article>, <section>, <aside> et <footer> couvrent l'écrasante majorité des structures de pages réelles. Ajoutez <figure>, <time> et <address> là où ils s'appliquent, n'utilisez ARIA que quand le HTML natif est insuffisant, et vous aurez un balisage vraiment agréable à travailler.