Choix d'une DTD: le doctype switching n'est pas pour nous

Nouvel intervenant dans Alsacréations, à l'invitation de Raphaël Goetter (qu'on ne remerciera jamais assez), j'ai le plaisir de vous y proposer un premier tutoriel consacré à ces fameuses Déclarations de Type de Document (DTD) HTML4.01 et XHTML1.0, parmi lesquels il paraît parfois difficile de faire son choix. Sans entrer ici dans les détails (je vous laisse lire le tutoriel), disons simplement que ce choix est en réalité très simple, si vous l'abordez avec quelques questions élémentaires qui conviendront à la majorité des situations. Pour reprendre la conclusion de ce tutoriel :

  • XHTML1.0 ne sépare pas plus le contenu et la présentation qu'HTML4.01 : dans les deux cas, c'est en fait le choix entre strict et transitional qui fait la différence ;
  • Aucune de ces DTD n'apporte plus d'accessibilité a priori : XHTML1.0 n'est pas plus accessible qu'HTML4.01. C'est l'usage que vous en ferez qui fera la différence ;
  • XHTML1.0 n'apporte aucun gain “sémantique” par rapport à HTML4.01, dont il reprend les éléments et la quasi-totalité des attributs. Là encore, c'est ce que vous en ferez qui fera la différence.
  • Mais XHTML1.0 n'est pas plus difficile à apprendre qu'HTML4.01, au contraire : la syntaxe rigoureuse limite les risques d'erreurs ;

Mais il y a un point sur lequel j'aimerai insister ici : celui du doctype switching, le "changement selon le doctype" et des raisons pour lesquels vous ne devez pas vous en servir pour régler un problème de mise en page.

Tout d'abord, de quoi s'agit-il ?

Ce mécanisme, considéré aujourd'hui comme une des principales clés de l'implémentation des standards, a été inventé... par Microsoft, ou plus exactement par les ingénieurs responsables d'IE5Mac. Salué en son temps comme une avancée révolutionnaire vers les Standards Web, ce navigateur était en effet le premier de l'époque à implémenter de manière fiable une partie du standard CSS. Ce qui posait un problème de taille : traitées selon les règles de ce standard, les pages Web codées à l'ancienne, optimisées pour Internet Explorer Windows, ou pour Netscape... auraient donné le plus souvent des résultats catastrophiques dans un IE5Mac coupable de trop bien respecter les standards Web.

A titre d'exemple, prenons le cas des tailles de caractères : celles-ci, selon les standards CSS, sont héritées par les éléments descendants. Autrement-dit, il vous suffit de préciser la taille de caractères pour l'élément body, et toute votre page en héritera. Mais ce n'était pas le cas des navigateurs de l'époque : pour les Netscape 4.x d'alors, ces tailles n'étaient pas héritées dans les tableaux, alors abondamment utilisés pour la mise en page. Du coup, dans les pages conçues pour ces navigateurs, la taille des caractères était précisée pour chaque élément du tableau, à l'aide de quelque-chose que nous pourrions résumer, en langage moderne, par : body, td, th {font-size: 0.8em;}.

Et alors, me direz-vous ? Où est le problème ? Eh bien :

  • Si vous n'appliquiez pas les règles standards d'héritage, le texte de vos cellules faisait bien, comme prévu, 80% de la taille par défaut ;
  • Mais si vous appliquiez les règles standards d'héritage à ce tableau, la taille se réduisait par héritage d'élément en élément, pour finir par des cellules dont les caractères ne faisait plus que 50% de la taille par défaut. Pour peu que des tableaux eussent été imbriqués, ce qui était souvent le cas, le texte pouvait finir par arriver à une taille... sub-atomique !

Ce n'est qu'un simple exemple des multiples problèmes de compatibilité soulevés par le passage à une interprétation "standard" par un navigateur conçu à l'origine pour traiter le tout venant du Web. Ces problèmes ne se limitent d'ailleurs pas au rendu CSS, mais concernent également le DOM (javascript, si vous préférez). Si vous êtes curieux, vous trouverez d'excellentes introductions à ce sujet éminement scabreux dans les classiques :

Retenons ici qu'il fallait donc trouver un moyen permettant à IE5Mac de différencier :

  • les pages anciennes manières à traiter à l'ancienne ;
  • les pages “standards” à traiter selon les normes HTML-CSS-DOM.

Ce moyen, ce fut le doctype switching :

  • en présence d'une DTD HTML4.01 ou XHTML1.0 complète, bien rédigée, le navigateur savait qu'il avait affaire a priori à une page à traiter selon la norme ;
  • en l'absence de DTD, ou en présence d'une DTD incomplète telle qu'on la rencontrait alors fréquemment, ou d'une DTD "non W3C", le navigateur présumait qu'il s'agissait d'une page à traiter en mode de compatibilité avec ses précédentes implémentations non standards.

Initié par IE5Mac, le mécanisme du doctype switching a connu un succès fulgurant, et a été adopté rapidement par tous les autres navigateurs. Chacun à sa manière, selon ses propres règles plus ou moins cohérentes avec celles de ses rivaux, nos navigateurs modernes switchent tous allègrement entre, au moins, deux modes de rendu : le mode Strict (conformité au standard) et le mode Quirks (compatibilité avec les anciens modes de rendu). Le doctype switching, loin d'être une péripétie de l'histoire des navigateurs, est encore aujourd'hui un mécanisme essentiel du Web rétro-compatible.

En quoi est-ce que cela me concerne ?

Si vous pensez en lisant ces mots : “Bon, c'est intéressant, mais ce mécanisme assumé par le navigateur est totalement transparent pour le développeur de site qui a choisi de respecter les standards”... Alors, heureux webmestre que vous êtes, ce qui suit ne vous concerne pas. Continuez à utilisez les DTD complètes, indiquées par le W3C, et retournez à vos travaux, la conscience tranquille.

Si, en revanche, vous êtes en train de vous dire quelque-chose comme : "Ah... C'est donc pour cela que mes pages vont bien seulement quand j'utilise une DTD un peu plus courte, ou telle DTD bien précise", du type : <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">... Alors, lisez attentivement ce qui suit :

Le piège du doctype switching

Imaginons, par exemple, que j'aie callé au pixel près une superbe mise en page CSS2 sans tableaux de présentation. Je constate, inévitablement, des problèmes de rendu dans tel ou tel navigateur : les uns vont en effet calculer mes largeurs de boîte d'une certaine manière, les autres vont les calculer selon le standard CSS ; les uns vont appliquer le modèle de calcul des padding CSS, d'autres une version très personelle de celui-ci ; etc. Il existe encore bien d'autres raisons expliquant mon problème.

Dans tous les cas, le rendu au pixel près est une coûteuse illusion, dont nous reparlerons un autre jour, mais restons-en pour l'instant à ce constat : finalement, le résultat d'un navigateur à l'autre ne me convient pas.

Que se passe-t-il ? Les standards sont-ils en cause ? CSS est-elle donc une norme illusoire ? Non : le problème est ailleurs.

J'ai tout simplement conçu ma mise en page selon un modèle hors-norme, celui du modèle de boîte CSS propre à Microsoft, ou bien son implémentation très personnelle de la propriété width, ou etc. : je me suis en fait fourvoyé en ne suivant pas le standard CSS. J'aurais pu tout aussi bien développer, sans le savoir, en fonction de telle ou telle autre implémentation propre à un navigateur ou à un autre.

Que faire ? Ou plutôt, que ne faut-il surtout pas faire ? Tout simplement, il ne faut surtout pas choisir alors la DTD de manière à résoudre ce problème de rendu sans rien changer au code CSS (ou javascript, ou HTML). En effet, cela consiste à adopter une de ces DTD, par exemple incomplètes, qui vont basculer tous les navigateurs en mode de rendu Quirks. Du coup, ma page est affichées correctement... sur la base d'un modèle de développement propriétaire, non standard, et totalement dépassé.

En outre, chaque nouvelle version de chaque navigateur est susceptible de modifier son mode de rendu Quirks, sans crier gare et de manière tout à fait arbitraire : seul le mode de rendu Strict garantit qu'il ne changera que si la norme elle-même change.

En d'autres termes, en faisant ainsi, je vais reconduire et reproduire des pratiques de codage peu fiables, auxquelles il s'agit justement de mettre fin. Le doctype switching est fait pour traiter les anciens contenus qu'on ne pourra pas mettre à jour, pas pour en générer de nouveaux sur le même modèle défectueux ou problématique.

Que faire ?

Les règles de bonne pratique de codage que l'on peut recommander sont simples :

  • Pour ne pas reconduire d'anciens modèles périmés, ne pas développer dans un navigateur à l'implémentation HTML/CSS réputée défectueuse. Autrement dit, ne pas prendre en particulier Internet Explorer 6.0 Windows comme navigateur-type. Lui préférer les navigateurs modernes implémentant strictement les formats HTML et CSS, tels qu'Opera, Firefox, Konqueror. Nous espérons tous pouvoir développer dans un avenir plus ou moins proche dans un IE7 respectueux des standards, mais ne confondons pas aujourd'hui IE6.0 et cet éventuel IE7 ;
  • Ne pas utiliser une autre DTD que celles recommandées par le W3C, autrement-dit, pour les 2 principales :
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    
  • Sur un point de détail parfois rencontré : ne pas jouer sur le fait qu'un prologue XML, ou tout autre contenu placé avant la DTD, va basculer Internet Explorer Windows, et lui seulement, en mode de rendu Quirks : si vos documents sont en XHTML1.0 sans que vous sachiez gérer les types mimes text/html et application/xhtml+xml, il ne faut pas mettre ce prologue XML (du type <?xml version="1.0" encoding="UTF-8"?>) qui n'a en fait aucun sens dans le mode où vos pages seront traitées.

En conclusion : laissons le doctype switching rester le mécanisme transparent qu'il a été conçu pour être, sans jouer volontairement avec lui pour régler (illusoirement) un problème de rendu d'affichage ou de comportement. Ceci est d'autant plus important que, dans les mois à venir, le futur IE7 va sans doute faire reposer ses progrès CSS sur ce mécanisme du doctype switching...

Dans ce type de situation, plutôt que de s'enferrer dans des pratiques problématiques, la meilleure démarche est de remettre l'ouvrage sur le métier, et de revoir entièrement si nécessaire la mise en page, le comportement ou la structure concernés.. cette fois-ci selon les standards ;)

Trackbacks

Aucun trackback pour le moment.

Les trackbacks pour ce billet sont fermés.

Evaluez ce billet

Commentaires

Le lundi 1 août 2005 à 15:41, par YoGi :: site :: #

c'est sympa tout ça mais il ne faut pas perdre de vue que dans certains cas le développeur web n'a pas le choix du doctype, si celui-ci est généré automatiquement par un serveur d'application, par exemple (c'est le cas d'IBM Lotus Domino, d'Oracle 9iAS Portal..). D'ailleurs souvent le code généré par ces systèmes sont de véritables horreurs (je songe notamment à Oracle Portal qui génère 36000 body dans un même document).

Je sais qu'en réalité je suis ici hors-sujet, il s'agit d'un article technique pour expliquer un mécanisme, je regrette cependant qu'on apporte souvent de fausses solutions puisqu'impossibles à appliquer dans l'environnement de l'entreprise.

Le lundi 1 août 2005 à 16:51, par Cerebral :: site :: #

C'est une bonne chose d'avoir rappellé l'utilisation/omission du prologue XML car on insiste souvent pas assez sur cet aspect qui joue un rôle primordial dans IE.

Le mardi 2 août 2005 à 01:56, par Roro :: #

D'ailleurs Cerebral, si tu as plus de détails sur cette utilisation/omission et ses conséquences, je suis preneur ;)

Le mardi 2 août 2005 à 02:25, par vero :: #

Le tuto qu'il nous fallait !

Avec le temps, cela finit par rentrer mais un recapitulatif n'est pas de trop (pour les mémoires tendance "gruyère" !)

Bon, une question, tout de même, concernant ce prologue XML :

Il fait basculer IE, si j'ai bien compris ...

Mais, sous Dotclear (dans lequel il est prévu) il n'apparait pas dans le source généré sous IE.

Donc : pas de problème, il ne gêne plus personne et il devient inutile d'aller trafiquer le moteur pour l'oter.

N'est-ce-pas ?

Le mardi 2 août 2005 à 06:16, par Laurent Denis :: #

Bon, un petit rappel sur le prologue XML, alors (on en fera un tuto complet et plus développé si cela vous intéresse) :

Le prologue XML, tout d'abord, n'a de sens que si le document XHTML est traité en tant que XML, c'est à dire envoyé au navigateur avec le type mime application/xhtml+xml (Cas non visé par l'article ci-dessus et le tutoriel qui y est cité) : il permet alors de rappeler le type de contenu (application/...) et l'encodage du document.

Dans un document XHTML qui sera traité en tant que HTML (type mime text/html), il n'est d'aucune utilité et n'est qu'une bizarrerie de plus dans ce que le navigateur interprète comme un bon vieux HTML des familles un peu mal écrit. L'encodage et le type de contenu sont rappelés en effet dans la <meta http-equiv="Content-Type" ... />, qui joue le même rôle que le prologue XML précédent.

Précisons que cette meta ne DOIT PAS figurer dans un document XHTML traité en tant que XML, sous peine de le rendre non conforme.

Autrement dit :
- XHTML traité en tant que XML => prologue: oui. Meta: non.
- XHTML traité en tant que HTML => prologue: non. Meta: oui.

Maintenant, même dans le cas du XHTML traité en tant que XML, ce prologue reste en fait optionnel:
- si l'encodage du document est utf-8 ou utf-16 ;
- ou si un encodage autre que utf-8/utf-16 a été indiqué à un niveau supérieur, c'est à dire dans l'en-tête HTTP Content-Type.

En pratique, et pour résoudre ces coupages de cheveux en quatre : le type de contenu et l'encodage d'un document HTML ou XHTML traité de la façon que vous voudrez doivent toujours être indiqués tous les deux par cet en-tête HTTP. Le prologue XML et la <meta> équivalente ne servent qu'à rappeler localement ces informations, dans l'hypothèse où le document serait enregistré par l'utilisateur, ou déplacé sur un autre serveur, et où l'en-tête HTTP serait donc perdu.

En fait, un navigateur intelligent enregistrant un document sur le poste client devrait se charger tout seul d'ajouter le prologue ou la meta à la source (X)HTML...

Et pour en revenir à IE6 : n'importe quel chaîne de caractères (non espaces) placée AVANT la DTD va le faire basculer en mode de rendu Quirks, quelque-soit la DTD. C'est un bug : il ne cherche la DTD qu'au premier caractère différents d'une espace. Un bête commentaire en <-- --> ou en <![CDATA[... produira le même effet que le prologue XML.

Maintenant, si vous respectez les règles de conformité HTML et XHTML décrites ci-dessus, cette question du prologue IE6 ne se pose pas :
- vous n'en mettez pas en XHTML traité en tant que HTML, et IE travaille sagement en mode de rendu Strict
- vous en mettez un dans le XHTML traité en tant que XML... mais vous n'envoyez jamais à IE cette version de votre document, puisqu'il ne sait pas la traiter (au lieu de tenter de l'afficher, il propose son téléchargement).

C'est ce que fait DotClear lorsqu'on lui demande de gérer le blog en application/xhtml+xml :
- les navigateurs déclarant accepter ce type de contenu reçoivent la version avec le bon en-tête HTTP Content-type et le prologue XML
- les navigateurs muets sur leurs goûts en matière de type de contenu, comme IE, reçoivent la version sans prologue, en text/html.

Bon... En relisant tout ça, je me dis que ce serait sans doute mieux de prendre un peu plus de temps pour l'expliquer avec des exemples :D

Le mardi 2 août 2005 à 06:28, par Laurent Denis :: #

@YoGi> Le choix d'un serveur d'application de ce type peut en effet revenir à faire le choix de ne pas diffuser des documents formattés de manière standard. On est en fait dans le domaine des formats propriétaires, et des DTD "propriétaires" (qui n'ont rien de criminels, mais restreignent simplement l'interopérabilité des documents produits).

Autrement-dit, l'erreur consiste à vouloir opter pour les standards HTML4.01 / XHTML1.0 dans le cadre de ce type de solution, lorsqu'elles ne permettent pas une gestion suffisamment fine des DTD et du code produit ;)

Le mardi 2 août 2005 à 12:57, par Olivier :: site :: #

Concernant DotClear et le prologue XML, je n'ai pas pu me faire entendre à ce sujet :
www.dotclear.net/forum/vi...

C'était pourtant argumenté...
Il semble que dès qu'on touche à la sacrosainte machine, on se fasse chatier sur le champ.

Le mardi 2 août 2005 à 13:32, par YoGi :: site :: #

@Laurent : je crois que tu cherches un peu trop loin. Il n'y a aucune DTD (et par conséquent pas de propriétaire) dans le code, et du moment que ça marche sous IE les gens s'en fouttent.

Le mardi 2 août 2005 à 14:50, par Laurent Denis :: #

@Olivier : lol. Olivier (Meunier) peut être une sacrée tête de mule, en effet.

@YoGi : sauf erreur de ma part, BM Lotus Domino génère sa propre DTD (mais sans doute pas par défaut ni de manière obligatoire).

Le mardi 2 août 2005 à 15:43, par YoGi :: site :: #

@laurent: Euh.. je développe pour Domino quotidiennement depuis bientôt 2 ans, je n'ai jamais rien vu de tel. Peux-tu m'en dire plus ?

Le mardi 2 août 2005 à 16:25, par Laurent Denis :: #

@Yogi : effectivement, après vérification, il y avait bien erreur de ma part ;)

Le mardi 2 août 2005 à 16:38, par Vero :: #

@Laurent Denis :
Ben, sous Dotclear, le prologue XML est ajouté même avec xhtml traité en tant qu'html ...
sauf sous IE

d'où le topic sur lequel pointe Olivier.

@Olivier :
Je me fais chatier tout suite, ou j'attends encore un peu ?
lol

En fait, l'idée est d'éviter de faire des modifications trop nombreuses sur le moteur si elles ne sont pas nécessaires (plus facile à mainetenir) Non ?

Le mardi 2 août 2005 à 17:20, par Laurent Denis :: #

L'idée est en effet d'adopter, parmi les solutions conformes, celles qui privilégient la simplicité de maîtrise du rendu (pas de problème liés au prologue XML dans IE), de maintenance des outils, et la facilité d'apprentissage (Pas de "oui", "non", "zut" à propos de ce prologue) ;)

Le dimanche 14 août 2005 à 19:12, par curio :: site :: #

Perso, pour éviter une inconscistence de rendu entre IE5.x et IE6, je met toujours le prologue XML.


C'est la méthode la plus simple que j'ai trouvé.
Plus efficace en temps parce que ça permet de faire une version "IE" des hacks css obligatoires (les marges doubles, etc..) sans perdre trop de temps à prendre en compte les versions d'IE pre-doctype-switching.

Le dimanche 14 août 2005 à 20:08, par Laurent Denis :: #

Curio : les bugs CSS majeurs d'IE6.0 (tels que les problèmes liés aux flottants, aux calculs de marges ou de padding, etc) sont identiques en mode de rendu strict et quirks. La différence essentiel à ce stade est le modèle de boîte.
Tu n'auras pas plus de difficulté à traiter ces bugs en plaçant IE6 en mode strict.

Ajouter un commentaire

Les commentaires pour ce billet sont fermés.