Maîtrise HTML5 règles de cadrage

L'un des concepts les plus importants de HTML5 est le modèle d'analyse unifiée. Dans les versions précédentes de la spécification HTML, l'implémenteur avait beaucoup de liberté. Fondamentalement, on pourrait choisir comment gérer certains scénarios. La divergence qui en résultait était l’une des principales raisons des interprétations différentes de nombreux sites Web sur plusieurs navigateurs. Avec HTML5, la gestion des erreurs a été spécifiée de manière très détaillée, ne laissant aucune place aux interprétations..

Dans ce premier article de la série «HTML5 Mastery», nous examinerons les algorithmes de traitement des erreurs spécifiés dans la norme. Nous verrons que certaines de ces erreurs potentielles sont en réalité un comportement accepté, ce qui les rend utilisables dans des sites Web populaires. La partie principale de cet article abordera les règles de portée, qui couvrent la plupart des comportements expérimentés lorsqu’elles déclenchent certains algorithmes. Nous commençons par un exemple pratique montrant les balises de fermeture implicites.

Exemples concrets

Deux des capacités les plus utilisées d'un analyseur HTML5 normalisé sont la construction automatique d'une structure de document valide et l'insertion de balises de fin implicites. Nous commençons par ce dernier. Un très bel exemple pour illustrer cette fonctionnalité est la construction d’une liste simple. L'extrait de code suivant montre une liste non triée avec trois éléments.

  • Premier article
  • Deuxième article
  • Troisième item

Même si nous omettons la balise de fermeture (), la page affiche la bonne chose. Le rendu correct n'est possible que si l'arborescence DOM a été construite correctement à partir de la source donnée. L'arborescence DOM est la représentation des nœuds DOM dans une hiérarchie d'arborescence. Un nœud DOM peut être un élément, un commentaire, un texte ou une autre construction, introduite dans d'autres parties de cette série..

La hiérarchie de l'arborescence DOM commence à la racine et affiche les nœuds enfants de la racine. Une racine est le premier nœud d'un arbre. Il n'a pas d'élément parent. Certains nœuds, tels que les éléments, peuvent avoir leurs propres nœuds enfants. L'arbre nous donne des informations sur les DOM construits, alors que la source ne propose qu'une construction.

L'analyseur HTML5 garantit que les balises de fin omises sont insérées avant l'ajout de nouveaux éléments de liste. Cela correspond à notre intuition. Naturellement, nous pensons que la liste donnée doit comporter trois éléments. Avant HTML5, nous pouvions en fait nous retrouver avec un seul élément contenant du texte et un autre élément contenant à nouveau du texte et un élément contenant du texte..

Dans le navigateur, nous voyons le rendu suivant (côté gauche). Nous pouvons également examiner l’arborescence DOM pour vérifier si l’analyseur a géré le scénario correctement (à droite)..

Même si Opera (ici dans la version 31) a été utilisé pour créer les captures d'écran ci-dessus, le comportement est indépendant du navigateur comme spécifié dans la norme HTML5.

En regardant le code source de certains sites très populaires, nous verrons peut-être quelques bizarreries. Par exemple, la page d'erreur affichée par Google contient le balisage suivant..

    Erreur 404 (introuvable) !! 1   

404. C'est une erreur.

L'URL demandée /Erreur n'a pas été trouvé sur ce serveur. C'est tout ce que nous savons.

Même sans spécifier un ou élément, les éléments sont construits. Les paragraphes ont également impliqué des balises de fermeture. Apparemment, les paragraphes sont traités comme des éléments de liste. Ils ne sont pas imbriqués, du moins lorsqu'ils sont construits à partir des sources par un analyseur HTML5.

Par conséquent, le navigateur génère l'arborescence à droite, ce qui rendra la mise en page à gauche.

L'une des lignes les plus importantes du code précédent est la déclaration du type de document HTML5 correct. Sinon, nous pourrions nous retrouver en mode quirks, ce qui est essentiellement équivalent à un comportement indéfini en termes de développement inter-navigateurs..

Balises de fin implicites

Le comportement observé dans la section précédente repose sur la génération de balises de fin implicites. Le mécanisme de génération de balises de fin implicites fonctionne en fermant le nœud actuel alors que le nœud actuel est l’un des éléments suivants:

  • ou
    ou
  • ou
  • ou

Nous reconnaissons que cela a vraiment du sens pour toutes ces balises. Un paragraphe imbriqué n'est pas bien défini. De même des listes ou des options imbriquées. Ils n'ont de sens que dans un autre conteneur.

Un élément avec une balise de fin implicite n’est pas la même chose qu’un élément à fermeture automatique. Dans le standard HTML, il y a des éléments, tels que , ou , qui sont à fermeture automatique. Même s'ils sont des éléments, ils ne sont pas censés avoir d'enfants. L'analyseur les ferme immédiatement. Bien que XML désigne ces éléments avec une barre oblique finale, HTML encourage à omettre la barre oblique..

Portées HTML

Il existe de nombreux scénarios où la portée s'applique. En principe, une fois que l'analyseur HTML5 a rencontré certains éléments lors de la construction de l'arborescence, il vérifie si l'élément se trouve dans une certaine portée. Si tel est le cas, d'autres actions peuvent suivre. Sinon, l'élément actuel est généralement ignoré.

Le processus permettant de déterminer si un élément se trouve dans une portée donnée commence par examiner l'élément en cours. Si l'élément est l'hôte de la portée, nous sommes dans sa portée. Si l'élément se trouve dans un sous-ensemble spécial d'éléments spécifiés par la portée, nous ne sommes pas dans la portée. Sinon, nous continuons la recherche sur l'élément parent de l'élément actuel.

Le sous-ensemble d'éléments peut être divisé en cinq groupes. Chaque étendue sélectionne l'un de ces groupes pour spécifier les éléments d'exclusion. Ces cinq groupes sont nommés:

  1. Général
  2. Élément de liste
  3. Bouton
  4. Table
  5. Sélectionner

Les groupes d’éléments de liste et de boutons contiennent également tous les éléments du groupe général. Le groupe de table ne contient que et l'élément de table lui-même. Le groupe de sélection comprend tous les éléments sauf et .

Exemples de portée

Le groupe sélectionné peut être utilisé pour illustrer clairement ce que nous obtiendrons en utilisant ces règles de portée. Si, par exemple, nous fermons un élément select, il est vérifié si nous avons un

En fait, c'était trop facile. Notre intuition nous dit que le ferme également l'option et le groupe d'options. C'est correct. Nous sommes en fait limités à l’utilisation exclusive d’éléments d’option et de groupe d’options dans un élément sélectionné. Ceci est supervisé par l'analyseur. Alors, qu'en est-il maintenant?

Eh bien, il y a deux différences majeures ici. Premièrement, nous n'entrons pas dans un élément sélectionné. Donc et ne sera pas contraint par l'analyseur. Ils peuvent également prendre des éléments arbitraires. Deuxièmement, la fermeture de l'élément sélectionné sera ignorée. L'origine de ce comportement réside dans la règle de portée appliquée.

Examinons maintenant certains comportements susceptibles d’influencer votre conception de balisage. À quoi ressemblera l'arbre DOM construit pour l'extrait suivant?

Je viens de

Allemagne
.

Rien de plus facile que ça, n'est-ce pas? Eh bien, pas si vite. Le balisage peut sembler légal à première vue. Après tout, il s'agit simplement de déclarer sémantiquement une adresse à l'intérieur, non? Malheureusement non. le

Cet élément est également considéré comme un bloc, comme un paragraphe. Ce bloc n'a rien à voir avec CSS, nous ne pouvons donc pas changer le comportement en utilisant un autre afficher déclaration.

Nous voyons déjà que le DOM construit fait la différence (à droite). Le rendu suit juste (côté gauche).

Ce comportement s'applique à pas mal d'éléments. La spécification se lit comme suit:

Une balise de départ dont le nom est l'un des suivants: “adresse”, “article”, “aparté”, “blocquote”, “centre”, “détails”, “dir”, “div”, “dl”, “fieldset”, “Figcaption”, “figure”, “pied de page”, “en-tête”, “hgroup”, “menu”, “nav”, “ol”, “p”, “section”, “résumé”, “ul” […]

Tous ces éléments vont vérifier si nous avons un élément paragraphe dans le groupe de boutons. Si tel est le cas, le paragraphe sera fermé.

Il existe de nombreux autres endroits où les éléments de contexte / ancêtre importent réellement. Tout cela rend les extraits HTML hautement non locaux. Cependant, pour le moment, nous allons examiner un autre sujet de traitement des erreurs..

Reformatage et Tables

Commençons par une question simple. A quoi ressemble l'arborescence DOM pour le code suivant?

12345

Il n’est certainement pas très difficile de comprendre l’arbre obtenu avant 3, mais alors les problèmes commencent. Il n'y a pas vraiment de bon argument pour ce qui devrait arriver ensuite. C’est la raison pour laquelle un éditeur de navigateur a décidé d’introduire un algorithme, décrivant le fonctionnement du reformatage..

Premièrement, la balise gras de fermeture implique la fin de toutes les balises incluses. Dans notre exemple, cela concerne l'italique. Mais comme nous n’avons pas fermé la balise italique, nous devons la traiter spécialement. Une fois toutes les balises internes fermées, nous devons en ouvrir de nouvelles pour les balises de mise en forme implicitement fermées. Une balise de mise en forme est une balise normale qui correspond à un élément, ce qui a des conséquences (historiques) sur la mise en forme du texte contenu..

L'image suivante montre le résultat. L'arbre de gauche est la construction jusqu'à 3, tandis que l'arbre de droite illustre l'image complète après l'extrait de code..

En temps de CSS, la reconstruction des éléments de formatage peut être considérée comme dépassée, mais elle est loin d’être obsolète. Il n'est pas déclenché directement lorsque des éléments sont fermés, mais plutôt lorsqu'un nouveau texte est inséré..

Un autre sujet intéressant est le lien entre la mise en forme et les éléments de tableau. La gestion des erreurs dans les tableaux est assez étrange. Personne ne semble bien le faire intuitivement. Historiquement, il a été développé par de nombreux fournisseurs avec différentes philosophies.

Considérons un exemple à nouveau. Comment l'arbre DOM cherchera-t-il l'extrait suivant??

bbb
aaa
ccc

Seuls les éléments de section de table sont autorisés dans une

. Comme on l’a vu précédemment avec des éléments HTML de base (tels que ou ), l’analyseur s’occupe généralement de cela. Par exemple, si une ligne est ajoutée directement à une table, le la section est insérée automatiquement pour prendre soin de la rangée.

Il est donc naturel de placer l’élément de mise en forme en gras dans le . Mais, comme nous avons spécifié la mise en forme en gras pour le texte, nous avons toujours besoin de l’avoir pour n’importe quel texte (en dehors du tableau). Par conséquent, la première étape consiste à produire une table (après la élément), avec du texte (normal).

Après la fermeture de la ligne, nous rencontrons du texte supplémentaire. Ce texte est dans la table, mais il n'a pas été placé dans une cellule. Il doit donc être ajouté avant le tableau comme l’élément gras. La mise en forme en gras est toujours active, c’est-à-dire que le texte ne sera pas ajouté de manière autonome, mais doit être placé dans un étiquette.

Enfin, nous avons du texte en dehors de la table. Nous pouvons correctement deviner que ce texte doit venir après le tableau dans l'arborescence DOM, mais la question clé est: faut-il le formater? La seule réponse correcte est non, cela ne devrait pas. Pourquoi? La raison est que nous n’avons jamais fermé la balise gras. Puisque l'étiquette en gras a été déplacée de la table au corps, nous ne l'avons toujours pas fermée.

Le balisage de l'exemple précédent ne peut pas être considéré comme lisible, intuitif ou souhaité. Le comportement que nous avons vu est un modèle de récupération d'erreur au travail, rien qui devrait être désiré. J'ai choisi l'exemple pour illustrer le problème (et la solution montrée par l'analyseur) d'imbrication de balises incompatibles. La plupart du temps, de tels problèmes sont dus à des erreurs de fusion copier / coller ou de contrôle de version..

Conclusion

Connaître le fonctionnement interne de l'analyseur HTML5 est important. Cette connaissance conduit aux bonnes règles de minification, qui peuvent économiser de nombreux octets et du temps d'analyse. Nous avons aussi maintenant une compréhension de base de la gestion des erreurs induites par l’analyseur HTML..

Les règles de portée sont toujours apparentes dans le processus d’analyse HTML5. Nous traitons avec un processus extrêmement dynamique qui ne prend pas les éléments comme égaux ou inconnus. Au lieu de cela, nous avons un vaste ensemble de comportements spéciaux qui dépendent fortement de la portée actuelle, définie par l'élément considéré..

Nous avons également vu que deviner le bon arbre n’est pas toujours aussi intuitif qu’il devrait l’être. En général, nous devrions essayer d'éviter de telles zones problématiques.

Références

  • Spécification W3C
  • Comment fonctionnent les navigateurs: dans les coulisses des navigateurs Web modernes
  • Jon Hartley: Quel est le gros diff entre HTML4 et HTML5?
  • Fermer ou ne pas fermer les balises en HTML5
  • Tiffany B. Brown - HTML5 n'autorise PAS les balises «à fermeture automatique»