Comment faire du vrai HTML et pas du mauvais HTML à la sauce XHTML

Hier, je disais que livrer le XHTML avec le type mime text/html revient à faire du mauvais HTML. Pour répondre notament à Hugo, sur le fait de fermer ou pas les "mono-tags", je vais m'expliquer un peu.

Prenons comme base, le document HTML suivant, valide bien entendu :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="fr">
  <head>
    <title>html test</title>
    <meta name="expires" content="Fri, 18 Apr 2008 07:51:13 GMT">
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
    <link rel="stylesheet" type="text/css" media="screen" href="style.css">
    <link rel="shortcut icon"  href="/favicon.ico">
  </head>
  <body>
    <p>essai</p>
    <hr>
    <form name="essai" action="essai.php" method="post">
      <p><input type="text" name="essai" value=""></p>
    </form>
  </body>
</html>

Nous allons le modifier pour le mettre à la sauce XHTML, pour préparer la transition entre HTML et XHTML comme certains voudraient le faire croire. Cela donne ceci en fermant les différents tags, y compris les tags "vides" type <hr> :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="fr">
  <head>
    <title>html test</title>
    <meta name="expires" content="Fri, 18 Apr 2008 07:51:13 GMT"/>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
    <link rel="stylesheet" type="text/css" media="screen" href="style.css"/>
    <link rel="shortcut icon"  href="/favicon.ico"/>
  </head>
  <body>
    <p>essai</p>
    <hr/>
    <form name="essai" action="essai.php" method="post">
      <p><input type="text" name="essai" value=""/></p>
    </form>
  </body>
</html>

Ce document n'est plus valide en regard de la DTD HTML 4.01 strict alors qu'il le serait en XHTML 1.0 strict, au détail près qu'il faudrait remplacer l'attribut name de la balise form par un attribut id. Hallucinant, non ? En fait, on se retrouve avec deux erreurs character data is not allowed here et quelques avertissements NET-enabling start-tag requires SHORTTAG YES.

Passons aux explications. Il faut bien garder à l'esprit que le HTML aussi bien que le XHTML sont issus du SGML. En écrivant du SGML, on peut omettre aussi bien les tags ouvrants que les tags fermants (propriété ommissibility ou OMITTAG en grand breton) et on a aussi la possibilité d'utiliser une syntaxe réduite (propriété minimization ou SHORTTAG). En HTML, ces deux propriétés sont activées. La première est implémentée par la plupart des navigateurs (même s'il y a quelques bugs) ce qui permet d'écrire par exemple de manière parfaitement valide :
<p>Mon paragraphe sans balise fermante.
<p>Un autre paragraphe !
.
La deuxième n'est pas implémentée dans les navigateurs mais fait tout de même partie de la spécification d'où les erreurs renvoyées par le validateur. Cette propriété permet d'écrire en SGML de manière raccourcie <em/foo/ au lieu d'écrire <em>foo</em>. Pour ce qui est du XHTML, la propriété SHORTTAG est désactivée tandis que la propriété OMITTAG est bien activée.

Donc en HTML si j'écris <hr/ (qui provoque l'avertissement NET-enabling start-tag requires SHORTTAG YES), le fait que la propriété SHORTTAG soit à on, fait que c'est interprété comme <hr>. Du coup <hr/ et <hr> sont équivalents du point de vue HTML. En conséquences, <hr/> (Le fait de mettre un espace avant le slash ne change rien!) est équivalent à <hr>>, où le deuxième > ne fait pas partie du tag. Donc si on met le tag <hr/> dans body, le parseur va se plaindre et signaler une erreur character data is not allowed here puisqu'on ne peut mettre que des balises de type bloc comme fils de body ; le caractère non autorisé est le >. On n'a le même genre d'erreur si on ferme les tags meta ou link dans la partie head :
<link rel="stylesheet" type="text/css" media="screen" href="style.css"/> .

Le parseur lorsqu'il recontre le slash considère que le tag link est fermé et continue. Il trouve ensuite le caractère > et renvoie une erreur document type does not allow element "LINK" here suivi par d'autres messages encore moins clair. En fait, le parseur essaie de faire au mieux : il trouve un caractère isolé et comme ils ne sont pas autorisés dans la partie head, il consière que la partie body est commencée d'où les erreurs rencontrées.

Note: le document modifié serait en fait valide en HTML 4.01 transitional. En effet, la propriété OMITTAG est désactivée pour la version transitional.

Haut de page