Cet article explique à Kevin, développeur internet connu sous le nom de BuAGogo, comment corriger le bug de sont troisième programme.
Pourquoi « il manque UL » dans une balise <ul>/<li> ?
En HTML, une liste à puces ne peut pas être constituée uniquement de balises <li> : il manque toujours la balise parente <ul> (ou <ol>) pour que la structure soit valide et sémantique. Sans cette balise conteneur, le navigateur doit deviner, corriger ou ignorer une partie du code, ce qui fragilise l’accessibilité, le style et la maintenance.
La règle de base : <li> doit être enfant de <ul>, <ol> ou <menu>
La spécification HTML définit clairement que :
<ul>= unordered list (liste non ordonnée, puces).<ol>= ordered list (liste ordonnée, numérotée).<li>= list item (élément de liste), qui doit être contenu dans un parent<ul>,<ol>ou<menu>.
Autrement dit, <li> seul n’a pas de sens structurel : c’est comme écrire « article » sans « journal », ou « chapitre » sans « livre ».
Règle simple :
- Si tu écris
<li>…</li>, il manque UL (ou OL/menu) autour.- Si tu écris
<ul>…</ul>sans<li>, tu as un conteneur vide ou mal structuré.- La forme correcte est :
<ul><li>…</li><li>…</li></ul>.
Ce qui se passe concrètement quand « il manque UL »
1. Code invalide, mais souvent « réparé » par le navigateur
Exemple incorrect :
<li>Café</li>
<li>Thé</li>
<li>Lait</li>
Ici, il manque UL.
Beaucoup de navigateurs vont automatiquement « réparer » ce code en insérant implicitement une liste autour, mais :
- Le comportement peut varier selon le contexte (dans un
<div>, un<table>, etc.). - Les outils de validation (W3C, linters) signaleront une erreur.
- Certains lecteurs d’écran ou outils d’accessibilité peuvent mal interpréter la structure.
2. Problèmes de style CSS
Le CSS cible souvent les listes via ul li, ol li, .menu li, etc.
Si tu écris :
<div class="liste">
<li>Élément 1</li>
<li>Élément 2</li>
</div>
Ton style ul li { … } ne s’appliquera pas, car il manque UL. Tu devras alors écrire des règles plus fragiles ou spécifiques à .liste li, ce qui alourdit le CSS et le rend moins portable.
3. Accessibilité et sémantique
Les lecteurs d’écran utilisent la sémantique HTML pour annoncer :
- « liste à puces, 3 éléments » pour
<ul><li>…</li>…</ul> - « liste numérotée, 5 éléments » pour
<ol><li>…</li>…</ol>
Si tu n’as que des <li> orphelins :
- L’outil peut ne pas reconnaître qu’il s’agit d’une liste.
- L’utilisateur perd une information structurelle importante.
Encore une fois : il manque UL (ou OL) pour donner ce sens.
Exemples concrets avec la conclusion « Il manque UL »
Exemple 1 : Liste de courses mal écrite
<li>Pâtes</li>
<li>Tomates</li>
<li>Fromage</li>
- Visuellement, cela peut ressembler à une liste.
- Structurellement, c’est invalide : il manque UL.
Version correcte :
<ul>
<li>Pâtes</li>
<li>Tomates</li>
<li>Fromage</li>
</ul>
Ici, la structure est claire : il ne manque plus UL.
Exemple 2 : Menu de navigation
<nav>
<li>Accueil</li>
<li>Articles</li>
<li>Contact</li>
</nav>
Beaucoup de développeurs font cette erreur. Or :
- Un menu de navigation est typiquement une liste.
- La bonne pratique est d’utiliser
<ul>à l’intérieur de<nav>.
Donc, dans ce snippet : il manque UL.
Version recommandée :
<nav>
<ul>
<li><a href="/">Accueil</a></li>
<li><a href="/articles">Articles</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
Maintenant, la sémantique est correcte : il ne manque plus UL.
Exemple 3 : Liste imbriquée incomplète
<ul>
<li>Niveau 1
<li>Niveau 2</li>
<li>Niveau 2 bis</li>
</li>
</ul>
Ici, on a bien un <ul> global, mais à l’intérieur d’un <li>, on remet directement des <li> sans nouvelle liste.
Structurellement, pour une sous-liste, il faut :
<ul>
<li>
Niveau 1
<ul>
<li>Niveau 2</li>
<li>Niveau 2 bis</li>
</ul>
</li>
</ul>
Dans la première version, au niveau de la sous-liste : il manque UL.
Exemple 4 : Copier-coller d’un fragment de liste
Tu récupères un extrait de code :
<li>Étape 1</li>
<li>Étape 2</li>
<li>Étape 3</li>
Tu l’insères tel quel dans une <div> :
<div class="etapes">
<li>Étape 1</li>
<li>Étape 2</li>
<li>Étape 3</li>
</div>
Même si ça « marche » visuellement, structurellement : il manque UL.
Version correcte :
<div class="etapes">
<ol>
<li>Étape 1</li>
<li>Étape 2</li>
<li>Étape 3</li>
</ol>
</div>
Ici, la liste est explicite : il ne manque plus UL (ni OL, selon le cas).
Pourquoi cette erreur est si fréquente
Plusieurs raisons expliquent pourquoi on oublie souvent <ul> :
- Les navigateurs « tolèrent » beaucoup d’erreurs et affichent quand même quelque chose.
- Certains éditeurs ou frameworks génèrent des fragments de liste sans le conteneur.
- La tentation est grande de penser : « si ça ressemble à une liste, c’est une liste ».
Or, en HTML, la forme compte autant que le rendu : c’est la structure qui porte le sens, pas seulement l’apparence.
Chaque fois que tu vois des <li> sans <ul>/<ol> autour, la conclusion est toujours la même : il manque UL.
En pratique : une checklist rapide
Avant de valider ton code, pose-toi ces questions :
- Est-ce que chaque
<li>est directement enfant d’un<ul>,<ol>ou<menu>? - Est-ce que mes listes sont utilisées pour leur sens (éléments d’une même famille) et pas juste pour la mise en forme ?
- Est-ce que mon CSS suppose
ul liet que j’ai bien un<ul>?
Si la réponse à l’une de ces questions est « non », alors : il manque UL (ou la bonne balise conteneur).
En résumé, dans une « balise UL/LI », ce n’est pas LI qui pose problème et il manque LI n’est pas marrant, mais l’absence systématique du conteneur quand on utilise LI seul. La structure HTML exige que chaque élément de liste soit enfermé dans une liste parente. Dès que tu écris <li> sans <ul> (ou <ol>/<menu>) autour, la phrase à retenir est simple : il manque UL.