Прочитав комментарии к заметке Firefox 3: * {display: block } bug, понял что заметная часть читателей Хабра, в том числе серьёзно занимающиеся веб-разработкой, не совсем верно представляют себе что-то же такое HTML, и почему теги отображаются так, а не иначе.



Как всегда, начнём с истории



Всё это уже писалось тысячи раз, но тем не менее. HTML ведёт свою «родословную» от разработанного IBM в конце 60-х годов прошлого уже века языка GML, предназначенного для универсальной системы обмена документами. В середине 80-х его наследник прошёл стандартизацию ISO и получил название SGML и, наконец, в начале 90-х на его основе Бернерс-Ли разработал HTML.

А можно так: мухи отдельно, котлеты отдельно?

Можно. И даже нужно. Именно так решили специалисты IBM, разрабатывающие GML, и отделили смысловое значение элементов документа (логическую структуру) от их внешнего вида (представления). Логика документа (значение составляющих его частей) — это неотъемлемая часть самого документа, а внешний вид было решено контролировать через внешние файлы стилей.

Правила составления документа (список тегов и правила их использования) также были вынесены во внешние файлы — DTD.

В итоге мы получаем систему из трёх компонентов:
  1. DTD — Определение правил использования элементов разметки.
    Документы — Данные, размеченные в соответствии с правилами DTD.
    Файлы стилей — Определение внешнего вида элементов разметки


    HTML версий 1 и 2 включал в свою схему только первые два пункта и не предлагал авторам документов возможностей для подключения внешних файлов стилей, оставляя внешний вид документа на усмотрение браузера. Спецификация HTML 2.0 только давала рекомендации как стоит отображать те или иные элементы докум��нта.

    Бабло побеждает...

    С бурным развитием коммерции в Интернет в середине 90-х годов, средств HTML 2.0 стало не хватать. И предприимчивая Netscape — тогдашний лидер рынка браузеров, а в след за ней и Mircosoft, также желавшая урвать кусок пирога, начали внедрение в свои бразузеры разнообразных «расширений» языка HTML. Фактически превратив его из языка разметки в язык оформления. Часть нововведений нашла своё отражение в HTML 3.2 в виде таких атрибутов как background, color и тегов наподобие font.

    CSS спешит на помощь1

    В 1996 W3C утверждает спецификацию CSS — таблиц стилей, призванную прекратить бардак и вернуть HTML его первоначальное назначение — определять смысл элементов документа, а не их внешний вид. Т.е. дать HTML тот самый 3-й компонент, который был у GML.

    Однако ничто не проходит бесследно. Эра браузерных войн и HTML 3.2 наложила серьёзный отпечаток как на движки браузеров, вынужденные поддерживать «расширения» HTML, так и на умы вебмастеров, привыкших смешивать воедино логику и представление.

    Как браузеры определяют оформление элементов?



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

    Например, определение тега style говорит что тег может содержать внутри себя данные типа CDATA, для него допустимы атрибуты интернационализации (lang, dir) а также атрибуты type, media и title.

    Теги p и hr описаны одинаково, за исключением того, что у hr не может быть содержимого, а p может содержать данные строчного типа.
    Обращаю внимание, что в DTD нет никаких указаний на то что hr надо отобразить горизонтальной линией, а p добавить вертикальные отступы!

    Так как же браузер узнаёт, что у p должны быть отступы, а strong — надо вывести жирным шрифтом? Ну а что у нас вообще отвечает за внешний вид? Да, 3-й компонент модели GML — стили. В случае с HTML — это CSS.

    Если в FireFox открыть URI: resource://gre/res/html.css, то можно увидеть те самые стили, котрые он применяет по умолчанию к HTML-документам.

    Вот стиль для параграфа:
    p, dl, multicol {
      display: block;
      margin: 1em 0;
    }
    

    А вот для горизонтальной черты:
    hr {
      display: block;
      height: 2px;
      border: 1px inset;
      margin: 0.5em auto 0.5em auto;
      color: gray;
      -moz-float-edge: margin-box;
      -moz-box-sizing: border-box;
    }
    
    hr[size="1"] {
      border-style: solid none none none;
    }
    

    Правда, всё просто и логично?

    Вернёмся к поведению, описанному в Firefox 3: * {display: block } bug, и посмотрим, какими правилами руководствуется FireFox при отображении основных блоков документа:
    html, div, map, dt, isindex, form {
      display: block;
    }
    
    body {
      display: block;
      margin: 8px;
    }
    ...
    /* hidden elements */
    area, base, basefont, head, meta, script, style, title, noembed, param {
       display: none;
    }
    

    Что же мы имеем в итоге? А в итоге у нас есть такая последовательность правил:
    area, base, basefont, head, meta, script, style, title, noembed, param {
       display: none;
    }
    ...
    * {
       display: block;
    }
    

    Согласно правилам каскадирования, определённым CSS 2.1, правила автора приоритетнее правил пользовательского агента, соответственно второй стиль перекрывает первый и все элементы документа, включая теги head и style становятся блочными и содержимое тега style, имеющее тип CDATA (см. выше) выводится в браузер.

    Видимо аналогичным образом поступают и Opera с Safari и Konqueror.

    Впереди планеты всей...


    … как всегда Internet Explorer. Трудно сказать, как обрабатывает документы браузер от Microsoft, но судя по ряду признаков, основываясь не на DTD и стилях, а каком-то собственном представлении об HTML. Видимо сказывается наследство времём HTML 3.2.

    Заключение


    Помимо стандартов «де-юре», в веб, как и в других областях, есть множество стандартов «де-факто» имеющих исторические корни. Такие стандарты воспринимаются многими как данность, вырабатывая некоторую инерцию мышления. Сталкиваясь с чем естественным, предсказуемым, но нарушающим привычный порядок, обладающие такой инерцией оказываются удивлёнными, объявляют непривычное ошибкой.

    Но хотелось бы напомнить пословицу: доверяй, но проверяй! И случается что на проверку, ошибка является вовсе не ошибкой, а следствием незнания, непонимания или той самой инерции мышления.


    Ссылки








    1 Название главы в книге Эрика Мейера «CSS — каскадные таблицы стилей»