Подтвердить что ты не робот

Почему теневой тег</p> создает пустой абзац?

По-видимому, если у вас есть тег </p> end без соответствующего начального тега внутри элемента body, большинство, если не все браузеры будут генерировать пустой абзац на своем месте:

<!DOCTYPE html>
<title></title>
<body>
</p>
</body>

Даже если какой-либо текст существует вокруг конечного тега, ни один из них не является частью этого элемента p - он всегда будет пустым, а текстовые узлы всегда будут существовать сами по себе:

<!DOCTYPE html>
<title></title>
<body>
some text</p>more text
</body>

Если вышеуказанное содержимое body завернуто в теги <p> и </p>... Я оставлю вас догадываться, что происходит:

<!DOCTYPE html>
<title></title>
<body>
<p>some text</p>more text</p>
</body>

Интересно, что если тегу </p> не предшествует тег <body> или </body>, все браузеры, за исключением IE9 и старше, не будут генерировать пустой абзац (IE ≤ 9, с другой стороны, всегда будет создавать один, в то время как IE10 и выше ведут себя так же, как и все другие браузеры):

<!DOCTYPE html>
<title></title>
</p>
<!DOCTYPE html>
<title></title>
</p><body>
<!DOCTYPE html>
<title></title>
</p></body>

Я не могу найти никаких ссылок, в которых указано, что конечный тег без соответствующего начального тега должен генерировать пустой элемент, но это не должно удивлять, учитывая, что он даже не корректный HTML в первую очередь. В самом деле, я нашел браузеры для этого с помощью элемента p (и в какой-то мере это элемент br!), Но не объяснения причин почему.

Он довольно согласован между браузерами, использующими как традиционные синтаксические анализаторы HTML, так и синтаксические анализаторы HTML5, хотя и применяется как в режиме quirks, так и в стандартном режиме. Поэтому, вероятно, справедливо вывести, что это для обратной совместимости с ранними спецификациями или традиционным поведением.

Фактически, я нашел этот комментарий в ответ на несколько смежный вопрос, который в основном подтверждает это:

Причина, по которой <p> теги действительны, так что первоначально <p> был определен как маркер "нового абзаца", а не p, являющийся элементом контейнера. Эквивалент <br> являясь маркером "новой строки". Вы можете видеть, как это определено в этом документе с 1992 года: http://www.w3.org/History/19921103-hypertext/hypertext/WWW/MarkUp/Tags.html, и этот с 1993 года: http://www.w3.org/MarkUp/draft-ietf-iiir-html-01.txt Поскольку в предварительных датах веб-страниц изменения и браузеры браузера всегда были как можно более совместимы с существующим веб-контентом, всегда оставалось возможным использовать <p> таким образом.

Но это не совсем объясняет, почему парсеры рассматривают явный тег </p> end (с косой чертой) как простой... тег и генерируют пустой элемент в DOM. Является ли эта часть некоторого соглашения об обработке ошибок парсера от начала, когда синтаксис не был так строго определен, как он был больше недавно или что-то еще? Если да, то это где-нибудь зарегистрировано?

4b9b3361

Ответ 1

То, что требуется, задокументировано в HTML5. Смотрите http://dev.w3.org/html5/spec/tree-construction.html#parsing-main-inbody и выполните поиск вниз для An end tag whose tag name is "p", и он говорит:

Если стек открытых элементов не имеет элемента в области кнопок с тем же именем тега, что и маркер, тогда это синтаксический анализ ошибка; действовать так, как если бы был замечен начальный тег с именем тега "p", то переработайте текущий токен.

Что переведен на английский означает создание элемента p, если тег </p> нельзя сопоставить с существующим тегом <p>.

Почему это так, сложнее констатировать. Обычно это происходит из-за того, что некоторые браузеры в прошлом приводили к тому, что это происходило как ошибка, а веб-страницы приходили на то, чтобы полагаться на поведение, поэтому другим браузерам тоже пришлось это реализовать.

Ответ 2

HTML4 DTD утверждает, что конечный тег является необязательным для элемента абзаца, но требуется начальный тег.

объявление SGML для HTML4 указывает, что omittag 'yes', что означает, что можно использовать начальный тег.

Конечный тег следует SGML правила:

конец тега закрывается, возвращается к соответствующему стартовому тегу, все незакрытые промежуточные стартовые теги с пропущенными конечными тегами

Анонимные блок-блоки генерируются для встроенных элементов, таких как текстовые узлы, поэтому они не должны быть обернуты элементом абзаца.

В базе данных ошибок Mozilla есть поток, который объясняет это поведение:

Вот соответствующий комментарий Борис Збарский:

Собственно, насколько я понимаю, для правильного анализа SGML/HTML требуется, чтобы мы так поступайте. То есть, '<' следующего тега - действительный способ закрыть разметка предыдущего тега...

И суммируется Ян Хиксон:

Основной принцип работы здесь, по-видимому, заключается в том, что разметка фиксируется задерживанием любых закрывающих тегов до тех пор, пока все остальные открытые элементы не будут закрыты, и не предпринимаются попытки сделать DOM следовать DTD HTML.

Ссылки