Незакрытые/ошибочные теги HTML распространяются за их родительские

Я использую некоторые интересные функции, когда теги HTML не закрыты. Иногда браузер вставляет дополнительные открывающие и закрывающие теги для компенсации, а иногда просто вставляет закрывающий тег. Это лучше всего объясняется примерами:

С тегом <sup>:

first text node
<div> This is a parent div <sup>superscript tag starts IN parent</div> text OUTSIDE node of parent

Ответы

Ответ 1

Благодаря @Ankith Amtange я нашел пояснение о том, что происходит. Я напишу это здесь для будущих читателей.

Тег <s> проходит мимо своего родителя, потому что это элемент форматирования. Тег <sup> автоматически закрывается, потому что браузер ожидает закрывающий тег </sup> до конца родительского элемента.

Парсер HTML обрабатывает элементы по-разному в своем стеке, которые относятся к следующим категориям (source):

Специальные элементы

  • Следующие элементы имеют различные уровни специальных правил синтаксического анализа: HTML address, 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, h5, 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 и xmp; MathML mi, mo, mn, ms, mtext и annotation-xml; и SVG foreignObject, desc и title.

Элементы форматирования

  • Следующие элементы HTML - это те, которые входят в список активных элементов форматирования: a, b, big, code, em, font, i, nobr, s, small, strike, strong, tt и u.

Обычные элементы

  • Все остальные элементы, найденные при разборе документа HTML.

Объяснение (из связанной спецификации):

Наиболее часто обсуждаемый пример ошибочной разметки выглядит следующим образом:

<p>1<b>2<i>3</b>4</i>5</p>

Разбор этой разметки прост до "3". На этом этапе DOM выглядит следующим образом:

─html
 ├──head
 └──body
    └──p
       ├──"1"
       └──b
          ├──"2"
          └──i
             └──"3"

Здесь стек открытых элементов содержит пять элементов: HTML, body, p, b и i. Список активных элементов форматирования имеет только два: b и i. Режим вставки "в теле".

После получения токена конечного тега с именем тега "b" вызывается "алгоритм агентства принятия". Это простой случай, поскольку элементом форматирования является элемент b, а нет более удаленного блока. Таким образом, стек открытых элементов заканчивается только тремя элементами: HTML, body и p, тогда как список активных элементов форматирования имеет только один: i. Дерево DOM не изменено в этой точке.

Следующий токен - это символ ( "4" ), инициирует восстановление активных элементов форматирования, в этом случае только элемент i. Таким образом, создается новый элемент i для текста "4" node. После того, как маркер конечного тега для "i" также принят, и "5" Text node вставлен, DOM выглядит следующим образом:

─html
 ├──head
 └──body
    └──p
       ├──"1"
       ├──b
       │  ├──"2"
       │  └──i
       │     └──"3"
       ├──i
       │  └──"4"
       └──"5"