Soyez moderne, faites du HTML des 90′
Quoi? Faire des layouts à base de tables avec des blinks et des marquees partout? Non, remontons encore plus loin. Ce dont il est question, c’est du HTML originel, sans présentations, celui où on trouvait merveilleux de pouvoir afficher un document et d’en atteindre un autre simplement en cliquant sur un bout de texte. Un des efforts actuels pour rendre le HTML sémantique se concentre sur ce bon vieux HTML : POSH.
Distinguer contenu et présentation
Nous sommes tous aujourd’hui bien éduqués au CSS. Nous savons qu’il est important de séparer le contenu de la présentation et nous éprouvons du dégout lorsque nous voyons le code d’un de ces vieux sites écrit sur une ligne avec des tables (d’autant plus lorsqu’on doit le restaurer). Et pourtant, voici un exemple type de page que nous écrivons :
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <link href="css/styles.css" rel="stylesheet" type="text/css" /> </head> <body> <div id="header"> <div id="logo"></div> <div id="menu"> <ul> <li><a href="1">1</a></li> <li><a href="2">2</a></li> <li><a href="3">3</a></li> </ul> </div> </div> <div id="content_wrapper"> <div id="content_top"></div> <div id="content_middle"> <p>...</p> <div class="item"> <h3>Item 1 - <a href="#" class="item_toggle" onclick="Item.show();">show</a></h3> ... </div> <div class="item"> <h3>Item 2 - <a href="#" class="item_toggle" onclick="Item.show();">show</a></h3> ... </div> ... </div> <div id="content_bottom"></div> </div> <div id="sidebar"> <div id="site_nav"> ... </div> <div id="local_nav"> ... </div> </div> <div id="footer"> ... </div> </body> </html>
C’est très CSS, c’est très moderne et c’est exactement la même chose que d’utiliser des tables. Le problème ici est que, contrairement au but initial de CSS, la présentation n’est pas séparée du contenu.
Pourquoi cela pose problème?
Que vous soyez idéaliste ou pragmatique, cette manière de coder du HTML doit vous poser problème.
Pour les idéalistes, il est clair qu’il s’agit ici de la mise en échec des fondements du CSS. La présentation n’est pas séparée du contenu, le code est sale.
Pour les pragmatiques, le problème vient des moteurs de recherche. Nous savons aujourd’hui que google (plus de 90% des recherches en France) execute des analyses syntaxiques sur les pages qu’il trouve pour en déterminer la structure et les termes importants. Une sémantique faible et du code parasite est l’assurance d’une mauvaise indexation. Je ne dis bien sûr pas qu’il suffit d’une bonne sémantique pour être compétitif sur vos mots-clefs, mais un code clair en est la base.
La solution POSH
Heureusement, ce n’est pas une fatalité. Voici un petit programme d’amaigrissement de l’exemple précédent.
- Ne trouvez-vous pas curieux d’avoir un “<div id=”header”>”? C’est ici le travail d’un <h1> (ou autre <hN>). Le menu n’a pas strictement sa place dans le header, peut-être voudrons nous plus tard en faire une sidebar. Sémantiquement, utiliser un h1 est une bien meilleure solution. On peut se servir de CSS pour en faire un bloc (display: block;) avec le logo et la texture en images de fond, et positionner le tout comme il faut.
- Le menu n’a pas besoin d’être un div lui non plus, la classe menu peut très bien être appliquée au ul.
- Le div vide #content_top sert à appliquer une texture représentant le haut du bloc de contenu. La plupart du temps, la hauteur de la partie header d’une page est fixe. Pourquoi ne pas alors utiliser une background-image sur body pour remplacer #content_top? De la même manière, l’image de #content_bottom peut être intégrée à l’image de #footer. #content_wrapper n’est alors plus nécessaire.
- Les .item peuvent être placés dans une liste, car il s’agit effectivement d’une liste.
- De même pour les liens de la barre de navigation.
- Les liens sans cible servant à afficher le contenu des .item en javascript peuvent être remplacés par des événements javascript appliqués à .item h3 .
Reste le div #content_middle, que je ne supprimerai pas, mais renommerai #content. Il ne s’agit pas de supprimer tous les <div>, comme on veut parfois supprimer tous les <table> (les tables CSS sont une horreur sémantique). Contrairement à ce qu’on peut lire ça et là, <div> n’est pas vide de sens. C’est un diviseur (de la même manière, <span> est un enjambement).
Utiliser un diviseur a du sens dans le cas de #content, qui ne correspond à aucune autre balise. Cela est d’autant plus clair si on fait du php ou du ruby on rails, où #content est bien souvent seul dans un fichier et où le header et le footer sont inclus de manière externe.
Le code final
Au final, nous nous retrouvons avec ceci :
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <link href="css/styles.css" rel="stylesheet" type="text/css" /> </head> <body> <h1>Title</h1> <ul id="menu"> <li><a href="1">1</a></li> <li><a href="2">2</a></li> <li><a href="3">3</a></li> </ul> <div id="content"> <p>...</p> <ul class="item"> <li><h3>Item 1</h3></li> <li>...</li> </ul> <ul class="item"> <li><h3>Item 2</h3></li> <li>...</li> </ul> </div> <ul id="sidebar"> </ul><ul id="site_nav"> ... </ul> <ul id="local_nav"> ... </ul> <p id="footer">...</p> </body> </html>
Le code est maintenant pleinement sémantique: chaque balise a un sens fort, le contenu est dépourvu de parasite de présentation et un bot de moteur de recherche saura facilement extraire les informations importantes.
Quelques lectures supplémentaires