Las etiquetas HTML no cerradas/mal utilizadas se extienden más allá de sus padres
html5 html-parsing (1)
Gracias a @Ankith Amtange encontré la explicación de lo que sucede. Lo escribiré aquí para futuros lectores.
La etiqueta <s>
extiende más allá de su elemento primario porque es un elemento de formato . La etiqueta <sup>
se cierra automáticamente porque el navegador esperaba una etiqueta de cierre </sup>
antes del final del elemento principal.
El analizador de HTML
trata los elementos de forma diferente en su pila, que se dividen en las siguientes categorías ( source ):
Elementos especiales
- Los siguientes elementos tienen niveles variables de reglas de análisis especiales: la
address
HTML
,applet
,area
,article
,aside
,base
,basefont
,bgsound
,blockquote
,body
,br
,button
,caption
,center
,col
,colgroup
,dd
,details
,dir
,div
,dl
,dt
,embed
,fieldset
,figcaption
,figure
,footer
,form
,frame
,frameset
,h1
,h2
,h3
,h4
,h6
,head
,header
,hgroup
,hr
,html
,iframe
,img
,input
,isindex
,li
,link
,listing
,main
,marquee
,meta
,nav
,noembed
,noframes
,noscript
,object
,ol
,p
,param
,plaintext
,pre
,script
,section
,select
,source
,style
,summary
,table
,tbody
,td
,template
,textarea
,tfoot
,th
,thead
,title
,tr
,track
,ul
,wbr
yxmp
;MathML
''smi
,mo
,mn
,ms
,mtext
yannotation-xml
; yforeignObject
,desc
ytitle
SVG
.Elementos de formato
- Los siguientes elementos
HTML
son aquellos que terminan en la lista de elementos de formato activos:a
,b
,big
,code
,em
,font
,i
,nobr
,s
,small
,strike
,strong
,tt
yu
.Elementos ordinarios
- Todos los demás elementos encontrados al analizar un documento
HTML
.
Explicación (de especificaciones vinculadas):
El ejemplo más discutido de marcado erróneo es el siguiente:
<p>1<b>2<i>3</b>4</i>5</p>
El análisis de este marcado es sencillo hasta el "3". En este punto, el DOM se ve así:
─html
├──head
└──body
└──p
├──"1"
└──b
├──"2"
└──i
└──"3"
Aquí, la pila de elementos abiertos tiene cinco elementos: html
, body
, p
, b
, y i
. La lista de elementos de formato activos solo tiene dos: b
i
. El modo de inserción es "en el cuerpo".
Al recibir el token de etiqueta final con el nombre de etiqueta " b
", se invoca el "algoritmo de la agencia de adopción". Este es un caso simple, ya que el elemento de formato es el elemento b
, y no hay un bloque más lejano . Por lo tanto, la pila de elementos abiertos termina con solo tres elementos: html
, body
y p
, mientras que la lista de elementos de formato activos tiene solo uno: i
. El árbol DOM
no está modificado en este punto.
El siguiente token es un carácter ("4") que activa la reconstrucción de los elementos de formato activos, en este caso solo el elemento i
. Se crea un nuevo elemento i
para el nodo de texto "4". Después de que también se recibe el token de etiqueta final para la " i
", y se inserta el nodo de texto "5", el DOM
tiene el siguiente aspecto:
─html
├──head
└──body
└──p
├──"1"
├──b
│ ├──"2"
│ └──i
│ └──"3"
├──i
│ └──"4"
└──"5"
Me estoy topando con alguna funcionalidad interesante cuando las etiquetas HTML no están cerradas. A veces el navegador inserta etiquetas adicionales de apertura y cierre para compensar, y otras veces simplemente inserta una etiqueta de cierre. Esto se explica mejor a través de ejemplos:
Con la etiqueta <sup>
:
first text node
<div> This is a parent div <sup>superscript tag starts IN parent</div> text OUTSIDE node of parent
Con la etiqueta <s>
:
first text node
<div> This is a parent div <s>strikethrough tag starts IN parent</div> text OUTSIDE node of parent
Como puede ver en el primer ejemplo, el navegador cierra automáticamente la etiqueta <sup>
antes de que cierre su padre. Sin embargo, en el segundo ejemplo, el navegador parece cerrar la etiqueta <s>
antes del final de su elemento principal y luego inserta otro inicio <s>
después del elemento principal.
He <sup>
especificaciones <s>
y <sup>
. Parece que no puedo encontrar nada específico sobre cómo los navegadores interpretan y manejan las etiquetas no cerradas. Al menos nada que explique esta funcionalidad.
La razón por la que quiero saber esto es para un analizador de reducción de valores en vivo que estoy usando: los usuarios no pueden terminar sus etiquetas antes de analizar su origen.
Me gustaría saber cómo el navegador se ocupa de estas cosas, por lo que puedo programar para ese caso de uso. En la actualidad, el navegador maneja cerrar diferentes etiquetas de diferentes maneras (como puede ver en mis ejemplos).
¿Alguien sabe por qué el navegador hace esto? ¿O al menos conocer una lista de elementos que actúen igual?