Le merveilleux monde du HTML

Avant d'attaquer le vif du sujet, je vais repréciser de façon vulgarisée certaines notions ayant trait au fonctionnement des navigateurs et, plus particulièrement, de leur façon d'interpréter les différents documents. Historiquement, la nature d'un document est précisée par le DOCTYPE, une déclaration figurant en première ligne de toute page bien formée. Celle-ci permet au navigateur de savoir à quel type de MarkUp il a affaire et de le traiter en fonction. Par exemple, la déclaration d'un document HTML 4.01 Strict se présente comme suit:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

Un navigateur qui rencontre cette déclaration traite l'intégralité de la page comme du HTML 4.01 Strict, jusque là tout va bien. En l'absence d'une déclaration de DOCTYPE reconnaissable, le navigateur bascule en mode "gestion d'erreur" (on parle de "quirksmode" pour Internet Explorer ou de "tag soup" chez Mozilla). En effet, puisqu'il est impossible de déterminer quel type de MarkUp est utilisé et donc d'appliquer la norme correspondante, le navigateur va faire son possible pour rendre la page "à l'arrache". Donc en l'absence d'une déclaration en bonne et due forme, la page aura un aspect aléatoire en fonction des différents navigateur, ce que tout webdesigner digne de ce nom se doit justement d'éviter.

Rien de dramatique jusque ici ceci dit, tant que la ligne identifiant le DOCTYPE est bien présente, tout se passe bien dans le meilleur des mondes.

Et la norme XHTML arriva...

C'est là que ça se complique. En effet, un document XHTML est identifié par son DOCTYPE tout comme un document HTML, mais la norme W3C précise aussi que les pages XHTML devraient être servies avec le content-type application/xhtml+xml au lieu du text/html habituel. Mais c'est quoi un content-type? Pour simplifier, disons que c'est l'étiquette que le serveur met sur une page avant de l'envoyer à votre navigateur. Pour une image, par exemple, le content-type serait image/jpeg, pour une page HTML c'est text/html, et donc d'après les spécifications, pour une page XHTML c'est application/xhtml+xml. Ok donc pas de problème, suffit de mettre la bonne étiquette sur mes belles pages?

...Et non, justement. Le problème c'est qu'Internet Explorer ne comprend pas application/xhtml+xml, si un serveur lui envoie ça, il va ouvrir une boite de dialogue et proposer à l'utilisateur de downloader la page au lieu de l'afficher. Ce qu'il se passe en fait, c'est qu'IE ne dispose pas de ce qu'on appele un parser XML, autrement dit un moteur qui lui permettrait de lire et comprendre le XHTML et le l'afficher comme tel. Du coup, si on suit la norme XHTML à la lettre, de nombreux visiteurs seront dans l'incapacité totale de voir le site, et d'ailleurs c'est pas près de s'arranger.

Ah ben comment on fait alors?

Puisque de nombreux navigateurs sont en retard de plusieurs années et ne savent pas gérer le XHTML correctement, il est donc nécessaire de sortir de la norme et de feinter. La solution la plus répandue jusqu'à maintenant est de servir les pages XHTML avec un content-type text/html (c'est par exemple le comportement par défaut de DotClear). Pourquoi pas après tout? Puisque tous les navigateurs savent gérer le HTML, ça doit pas poser de problème! Et bien en fait si. Envoyer une page XHTML comme une page HTML a pour effet direct de faire basculer les navigateurs sur leur parser SGML au mieux, en mode gestion d'erreur au pire. Et ben ouais! Le navigateur s'attend à trouver une page HTML, à la place il trouve une page XHTML, donc c'est la panique pour lui.

Comme il vaut mieux une page qui s'affiche mal qu'une page qui s'affiche pas du tout, dans le cas d'IE (pour ne citer que lui) ça reste mieux que rien. Mais Mozilla, par exemple, dispose d'un excellent parser XML et en envoyant les pages en text/xml au lieu de l'utiliser on repose sur son parser SGML pour l'affichage du XHTML, ce qui est un pur gâchis.

C'est grave docteur?

Ce qui nous sauve, c'est que non, c'est pas "grave". En effet le XHTML 1.0 est une norme de transition entre le HTML et le XHTML, sa syntaxe est très proche de celle du HTML et est donc compatible. Pour synthétiser ce que j'ai expliqué jusque là, une page XHTML envoyée en text/html sera donc affichée comme du HTML par les navigateurs. Bien sur on y perd en performances, mais le résultat final reste relativement constant d'un navigateur sur l'autre puisque les MarkUps sont compatibles.

Finalement, cette solution adoptée par 90% des sites reste mauvaise mais viable. Seulement voilà, les normes XHTML 1.1 et XHTML 2.0 se détachent de plus en plus des normes HTML, et là pour le coup ça devient grave puisque les pages XHTML envoyées en text/html ne pourront plus être affichées correctement par les parsers SGML des navigateurs. Il faudra obligatoirement envoyer les pages XHTML en application/xhtml+xml pour faire basculer en mode XML les navigateurs qui le peuvent, ce qui aura pour effet de rendre impossible l'affichage des pages sur les navigateurs obsolètes.

En attendant, qu'est-ce qu'on peut faire?

En l'état actuel des choses, pour faire des pages respectant les normes mais visibles sur un maximum de plateformes, je vois les solutions suivantes:

  • Utiliser le XHTML 1.0 Transitional: Cette norme est précisément prévue pour être la plus compatible possible, ce qui signifie que vous pouvez parfaitement servir des pages XHTML 1.0 Transitional en tant que HTML (text/html) sans risque de constater des bugs d'affichage d'un navigateur sur l'autre.
  • Utiliser le XHTML 1.0 Strict: En respectant les recommandations de compatibilité, cette norme aussi peut être compatible mais il est déconseillé de servir des pages XHTML 1.0 Strict en tant que HTML. En revanche, il est possible d'adapter le Content-Type au navigateur du visiteur: on envoie les pages en tant qu'application/xhtml+xml aux visiteurs utilisant Mozilla et en tant que text/html aux visiteurs utilisant Internet Explorer.

Pour faire ce genre de bidouille, 2 lignes de PHP suffisent:

<?php
	// On vérifie le contenu de la directive 'Accept' envoyée par le navigateur.
	$allow_xml = (strpos($_SERVER['HTTP_ACCEPT'], 'application/xhtml+xml') !== false);
	header('Content-Type: '.($allow_xml?'application/xhtml+xml':'text/html'));
?>

De cette façon, la page sera envoyée en tant que XHTML aux navigateurs qui disposent des moyens pour l'afficher et en tant que HTML aux autres, au risque bien sur de ne pas bien être affichée si elle ne respecte pas les recommandations de compatibilité (mais de toutes façons c'est ça ou rien).

  • Utiliser le HTML 4.01: Peut être la solution la plus sage si vous voulez éviter de vous retrouver avec de graves problèmes de compatibilité... Sans compter qu'une page XHTML malformée est beaucoup plus lourde de conséquences qu'une page HTML malformée puisque les navigateurs ne disposent pas encore de mode gestion d'erreur pour le XML tandis que le quirksmode d'IE peut afficher n'importe quoi de façon plus ou moins correcte.
  • Ne pas utiliser le XHTML 1.1: Dans tout les cas, vous devez absolument éviter d'utiliser la norme XHTML 1.1 puisqu'elle est incompatible avec de nombreux navigateurs et qu'envoyer des pages XHTML 1.1 en text/html, en plus d'être une violation des spécifications, peut donner des résultats aléatoires (sauf si vos pages XHTML 1.1 n'utilisent que des éléments présents dans la norme XHTML 1.0, auquel cas... où est l'intérêt?).

Conclusion

De nombreux sites affichent fièrement un DOCTYPE XHTML 1.0 Strict (voir XHTML 1.1...) pensant être à la pointe de la technologie alors qu'en fait, ils reposent inconsciement sur la capacité qu'ont les navigateurs à afficher des pages HTML malformées, ce qui est tout simplement nuisible, d'autant plus que la plupart de ces pages ne valident même pas. Tant qu'à avoir des pages qui font basculer IE en quirksmode et Mozilla en tag soup, autant utiliser le HTML 4.01, le résultat final sera exactement le même avec des bugs en moins.

Si vraiment vous désirez utiliser le XHTML, il faut être bien conscient que pour l'instant il est très mal géré par une grande majorité des navigateurs et sera de toutes façons interprété comme du HTML 4.01 (ou pire, en quirksmode).

On ne peut que regretter de se retrouver dans cette situation paradoxale où la plupart des sites utilisent un standard qui n'est pas géré par une grande majorité des navigateurs, d'autant plus que cette norme date de Janvier 2000. Actuellement, à ma connaissance seul Mozilla n'a pas 6 ans de retard, ça fait peur...