Должен ли конечный тег закрыть все незакрытые промежуточные начальные теги с пропущенными конечными тегами? - PullRequest
4 голосов
/ 07 января 2012

Я неправильно читаю стандарт HTML 4.01 или это Google?В HTML 4.01, если я напишу:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
<html> <head> <body>plain <em>+em <strong>+strong </em>-em

Рендеринг в Google Chrome:

обычный + em + сильный - em

Кажется, это противоречит стандарту HTML 4.01, в котором основные правила SGML суммируются следующим образом: «конечный тег закрывается, возвращаясь к соответствиюначальный тег, все незакрытые промежуточные начальные теги с пропущенными конечными тегами ». ¹

То есть конечный тег </em> должен закрывать не только начальный тег <em>, но и закрытый<strong> начальный тег, и рендеринг должен быть:

обычный + em + strong -em

Комментатор указал, что оставлять теги открытыми - плохая практика, но это только академический пример.Не менее хорошим примером будет: <em> +em <strong> +strong </em> -em </strong>.Из стандарта HTML 4.01 я понял, что этот фрагмент кода не будет работать должным образом из-за перекрывающихся элементов: конечный тег </em> должен неявно закрывать <strong>.Тот факт, что он работал должным образом, был удивительным, и именно это привело к моему вопросу.

И оказалось, что я предложил ложную дихотомию в вопросе: ни Google, ни я не читали стандарт HTML 4.01 неправильно,Частный корреспондент w3.org указал мне на Web SGML и HTML 4.0, объясненный Мартином Брайаном, который объясняет, что «программа синтаксического анализа автоматически закрывает все открытые в настоящее время встроенные элементы., который был объявлен как имеющий пропущенные конечные теги , когда он встречает конечный тег для элемента более высокого уровня.( Если встроенный элемент, конечный тег которого не может быть пропущен, все еще открыт, однако, программа сообщит об ошибке в кодировке .) ” ² (выделение добавлено.) Обобщение Брайанастандарта SGML является правильным, а обобщение в HTML 4.01 неверно.

Ответы [ 6 ]

6 голосов
/ 07 января 2012

Некоторые теги могут быть пропущены (например, конечный тег для <p> или начальный и конечный теги для <body>), а некоторые нет (например, конечный тег для <strong>).Это первое, на что ссылается раздел спецификации, которую вы цитируете.Вы можете идентифицировать их с помощью использования тире в DTD :

<!ELEMENT P - O (%inline;)*            -- paragraph -->
  ^A p element
            ^ requires a start tag
              ^ has optional end tag
                 ^ contains zero or more inline things
                                       ^ Comment: Is a paragraph

То, что у вас есть, это не HTML-документ с пропущенным тегом, а недействительный псевдо-HTML-документ, которыйбраузеры будут пытаться выполнить восстановление после ошибок.

В спецификации (для HTML 4) не описано, как выполнять восстановление после ошибок, оставленное браузерам.

4 голосов
/ 07 января 2012

Заявление, приведенное в спецификации HTML 4.01, очень неясно или просто неверно для всех учетных записей.В HTML 4.01 есть определенные правила для пропуска конечного тега, и эти правила зависят от элемента.Например, конечный тег элемента p может быть опущен, конечный тег em никогда не может быть опущен.Оператор в спецификации, вероятно, пытается сказать, что конечный тег неявно закрывает все внутренние элементы, которые еще не были закрыты, в той степени, в которой допускается пропуск конечного тега .

Ни один браузер никогда не реализовывал HTML 4.01 (или любую более раннюю спецификацию HTML), как определено, с функциями SGML, которые формально являются его частью.Все, что в спецификациях HTML говорится о SGML, следует воспринимать как теоретическое, пока не доказано обратное.

HTML5 не меняет правила игры в этом отношении, за исключением того, что записывает правила обработки ошибок ..В простых вопросах, подобных этим, правила просто делают традиционное поведение браузера нормой.Они ориентированы на tagoup, рассматривая теги более или менее как команды форматирования: <em> означает «курсив», </em> означает «прекратить курсив» и т. Д. Но HTML5 также принимает меры для более формального определения обработки ошибок, чтобы, несмотря на такой тегПри использовании супа четко определено, какое дерево документов в DOM будет построено.

1 голос
/ 07 января 2012

В спецификации сказано, что:

Some HTML element types allow authors to omit end tags (e.g., the P and LI element types).

Это:

Please consult the SGML standard for information about rules governing elements (e.g., they must be properly nested, an end tag closes, back to the matching start tag, all unclosed intervening start tags with omitted end tags (section 7.5.1), etc.).

Применяется к элементам, в которых могут отсутствовать конечные теги.

Если вы посмотрите спецификацию элемента P , вы увидите:

Начальный тег: требуется , Конечный тег: необязательно

Итак, когда вы используете это:

<DIV>
<P>This is the paragraph.
</DIV>

Элемент P будет автоматически закрыт.

Но, если вы посмотрите на EM спецификацию, вы увидите:

Начальный тег: требуется , Конечный тег: требуется

Таким образом, это правило автоматического закрытия недопустимо, поскольку HTML-код недопустим.

Любопытно, что все браузеры демонстрировали одинаковое поведение с таким недопустимым HTML.

1 голос
/ 07 января 2012

Все современные браузеры используют синтаксический анализатор HTML5 (даже для HTML 4.01 содержимого), поэтому применяются правила синтаксического анализа HTML5.Дополнительную информацию можно найти в разделе Анализ документов HTML в спецификации HTML5 .

Структура HTML

  • HTML
    • ГОЛОВА
      • # text"" ()
    • ТЕЛО
      • # текст"обычный" ()
      • EM
        • #текст"+ em" (курсив)
        • STRONG
          • # текст"+ strong" (жирный / курсив)
      • STRONG
        • # text"-em" (жирный)
0 голосов
/ 07 января 2012

Если вы посмотрите на DOM в Chrome, щелкнув правой кнопкой мыши и произнесите элемент inspect, вы сможете сделать вывод, что поскольку ваши теги не совпадают, он применил алгоритм, чтобы решить, где вы ошиблись.Технически, он закрывает сильную метку в правильном месте.Тем не менее, он решает, что вы, вероятно, пытались сделать оба фрагмента текста жирным, поэтому он помещает последний -em в совершенно новый, дополнительный «сильный» элемент, сохраняя при этом «+ strong» в своем собственном «сильном» элементе.Мне кажется, что команда Chrome решила, что статистически вероятно, что вы хотите, чтобы обе вещи были жирными.

0 голосов
/ 07 января 2012

Если вы попытаетесь запустить ваш HTML через http://validator.w3.org/check, он пометит этот HTML как недопустимый.

Если ваш HTML недействителен, все ставки отключены, и разные браузеры могут сделатьваш HTML по-другому.

...