Doctype: зачем он нужен и с чем его едят

17 ноября 2008. Рубрики: Рабочие заметки; автор — Юлия Панина aka Княгиня.

Сейчас буду жаловаться. Долго и со вкусом. Начну издалека.

Театр начинается с вешалки, а страница html — с объявления типа документа, для краткости именуемого «доктайп» (doctype — document type declaration или dtd). Точнее, должен начинаться — в сети можно встретить немало сайтов без доктайпа. Ничего хорошего в этом нет; если сайт уже свёрстан без доктайпа, его лучше не трогать, но создавать заново лучше с доктайпом. Кстати, страницы без доктайпа трудно править, почему — расскажу дальше.

Доктайп сообщает браузеру данные о языке, на котором написан документ: тип языка (html/xhml), версию (html 4.1/xhtml 1.0), направление (strict, transitional, frameset). Для обработки документа существует набор формальных правил, «известных» браузеру. Если браузер получает правильный доктайп, он обрабатывает страницу в соответствии с этими правилами (в режиме стандартов — standard mode). Если не получает или получает неправильный, он переходит в режим обратной совместимости (quirks mode) и начинает обрабатывать код, как разработчики положили на его браузерную душу. Судя по результатам, души у браузеров сильно разные.

Откуда браузер знает эти правила? Об этом должны заботиться его разработчики. Формальное описание каждой из разновидностей html публикуется Консорциумом W3C, и на эти описания равняются разработчики браузеров. Или должны равняться: самый популярный браузер Internet Explorer до сих пор не полностью поддерживает стандарты w3c. Обещал исправиться к седьмой версии, но этого не сделал. Обещает исправиться к восьмой.

Итак:

Что делает доктайп?
Сообщает тип документа.
Кому?
Браузеру.
Зачем?
Для обработки кода по одинаковым правилам (по стандартам).
Кому от этого польза?
Прежде всего, верстальщику.

Поведение документа, свёрстанного по стандартам, предсказуемо и более-менее одинаково для всех основных браузеров; говорю «более-менее», потому что про баги IE не слышал только ленивый, однако даже с IE легче справляться в режиме стандартов. Кроме того, в режиме обратной совместимости не действует ряд возможностей css, доступных в режиме стандартов. Первое, что даёт себя знать при переходе в режим обратной совместимости — обработка полей и отступов, например, перестают работать отрицательные margin’ы, а также нарушается наследование свойств шрифтов (таблицы и табличные ячейки не наследуют размер шрифта). Если при починке сайта вы видите, что у вас шрифты ведут себя не так, как ожидалось, проверьте доктайп (вообще-то с этого надо начинать работу).

Отдельная песня — работа со страницей, которую верстал кто-то другой, и верстал с неправильным доктайпом или вообще без оного: такую страницу легче переверстать с нуля, чем «вот тут немножечко поправить». В режиме обратной совместимости браузеры понимают правки кто в лес, кто по дрова, а при попытке поставить правильный доктайп имевшаяся вёрстка может просто рассыпаться. Починка такой страницы порой напоминает работу пастуха: стоит зазеваться, как одна овца (браузер) бежит туда, другая — сюда, и как их поймать — неизвестно, а усилия по сохранению старой вёрстки напоминают смесь героизма с мазохизмом.

Поэтому доктайп, и только доктайп должен стоять в начале html-документа! Причём правильный. На своих личных сайтах я обычно применяю доктайп языка xhtml 1.0 strict (строгий):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

В шаблонах, свёрстанных для чужих сайтов, я применяю доктайп xhtml 1.0 transitional (переходный):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Эти два вида доктайпа относятся к синтаксису xhtml. Для синтаксиса html применяются:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd">

и

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">

соответственно. И особый доктайп нужен для страниц с фреймовой структурой:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

или

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
  "http://www.w3.org/TR/html4/frameset.dtd">

Спрашивается, откуда такая несправедливость? Требование жизни. На моих сайтах я отвечаю за каждый символ, и не допущу на них ничего такого, что могло бы оскорбить их стриктовую нравственность. Но я отлично знаю, что на сайте, отданном в чужие руки, очень быстро появятся баннеры и просто исходящие ссылки с атрибутом target, а контент-менеджеру рано или поздно кто-нибудь подскажет чудесные теги font, center, и прочие прелести, относящиеся к категории deprecated (нежелательных). Направление transitional их допускает, а strict — нет. Повлиять на будущих хозяев сайта я не могу, и потому готовлю его к суровым реалиям жизни. А сайты, находящиеся под моей непрерывной опекой, могут позволить себе быть чистоплюями.

Надо сказать, что использование нежелательных (deprecated) элементов и атрибутов никаких фатальных последствий не несёт, даже если на сайте стоит строгий доктайп. Обещают, что когда-нибудь в будущем браузер будет карать за отступления от стандарта отказом обрабатывать документ, но пока это будущее не видно даже на горизонте, и вопрос о нежелательных элементах носит идейный характер, а не практический. Но что простительно админу сайта, то непростительно верстальщику.

Ещё добавлю, что использование визуальных редакторов и html-текста часто приводит к тому, что на сайтах появляются куски кода, не влезающие ни в какой стандарт, даже в transitional; например, когда div или p запихивают в span. Однако и тут последствия носят локальный характер и полной гибели сайта не влекут.

Однако в жизни бывают случаи намного более серьёзные, чем использование нежелательных элементов, и даже серьёзней, чем запихивание div в span. Бывает, что нехорошие или просто несведущие люди посягают на самое святое, что есть на странице — на доктайп! И сейчас я поведаю несколько случаев, когда мне довелось столкнуться с последствиями.

  1. Я тогда была совсем зелёной, и это был мой первый опыт передачи собственной вёрстки в чужие руки. Свёрстанный шаблон был принят заказчиком и отправлен программисту для натяжки на движок. Спустя время приходит письмо от программиста: в ФФ и Опере всё нормально, а в IE6 (IE7 ещё не вышел) всё разъехалось. «Разъехалось» — самое мягкое слово для описания того, что произошло со страницей! Я, как начинающий, очень переживала от мысли «а что про меня люди подумают», и вцепилась в глючную страницу в поисках ошибки. В стилях не было ничего, способного вызвать такое расползание; не понимая, что происходит, я стала сравнивать размётку страницы с размёткой моего шаблона — строчку за строчкой. Разницы не было, но нумерация строк оказались сдвинута на одну. Я поднялась выше, в самое начало документа, и увидела на первой строке не мной вписанный код:

    <?xml version="1.0" encoding="utf-8"?>

    Я убрала строчку, и страница приняла нормальный вид. С этим я столкнулась впервые, но теорию мне преподали крепко, и я вспомнила, что эта строчка называется «декларация xml», и что в html страницах она не нужна.

    Дело в том, что для xml-совместимых документов пролог состоит из двух частей: необязательная декларация xml и обязательный доктайп. Современные браузеры понимают декларацию xml, но IE6 не терпит перед доктайпом ничего, и на эту декларацию реагирует переходом в режим обратной совместимости. Что и произошло в данном случае.

    Я указала программисту корень зол; оказалось, что ему кто-то сказал, что так полагается по стандартам. Да, полагается; только IE со счетов сбрасывать нельзя.

  2. Снова свёрстанный мной сайт, снова обращают внимание на некорректное поведение страницы — теперь во всех браузерах: центральная часть макета, трёхячеечная таблица с шириной 100%, стала растягиваться не по ширине документа, а по ширине окна, чего не должно было быть (при малом окне справа за его границей оставалось чистое поле). Я уже была опытнее, и когда поняла, что страница ведёт себя нестандартно, двинулась проверять доктайп. Оказалось, неведомый злодей заменил его на свой (должно быть, более привычный). Я сказала: «Ну, знаете!..», вернула свой доктайп, и страница заработала нормально.

  3. Самый страшный случай в моей жизни. Можно сказать, кошмарный.

    Я делала вёрстку под систему управления контентом rbcsoft. Всё шло чин-чинарём — блочная резиновая вёрстка, чистота кода (требования заказчика), дело дошло до прикрутки. И тут оказалось, что на страницах с моими шаблонами не работает функционал — почтовые формы и голосования. Сравнение моих шаблонов со стандартными, имевшимися на сайте, показало, что некий системный тег, который я, как здравомыслящий верстальщик, сохранила, но поставила после доктайпа, обеспечивает работу голосовалки только тогда, когда идёт в документе первым! (Он выводил строчку кода наподобие <!—a45b6ec4d4a3c—>.)

    Ужасу моему не было предела. Пришлось вывернуться наизнанку и написать файл хаков специально для IE, чтобы страница нормально отображалась в режиме обратной совместимости — работоспособность функционала была важнее. А на странице фотогалереи я попросила не использовать голосовалку, потому что закруглённые уголки для изображений в нестандартном режиме сверстать было невозможно (или сверхсложно). «Качественная вёрстка» пошла насмарку; к тому же система управления вставляла в код страницы кучу лишних спанов с нестандартными атрибутами; зачем — не знаю! До сих пор мне хочется верить, что это был просто кошмарный сон, и не более…

Отзывы (25) на «Doctype: зачем он нужен и с чем его едят»
  1. Сергей М. (2 комментария)

    Вот это в ИЕ точно выбешивает — пока что все XHTML страницы ими не являются, ведь нельзя использовать объявление XML…

    Ответить на этот комментарий
    • Княгиня (648 комментариев)

      Ага, а ещё он не поддерживает тип содержания (mime-type) application/xhtml+xml. Шестой не поддерживал, седьмой не поддерживает, восьмой, говорят, тоже поддерживать не будет… А с другой стороны, ходят слухи, что на передовую выйдет не xhtml, а html5. Однако выйдет он, или нет, а только мне удобнее работать с xml-совместимыми версиями: там, где правила строже, проблем меньше.

      Ответить на этот комментарий
  2. Сергей М. (2 комментария)

    А вот это, как я понимаю, еще неизвестно. И в xhtml, и в html5 будут новые семантические теги, причем и там, и там добавление некоторых — избыточно, а других — очень хотелось. Вот соединить бы их лучшие качества :)

    ИЕ8 вроде как объявление xml будет поддерживать, да и мим должен бы. Не знаю, надо на бете посмотреть. В принципе, если даже только первое, то пойдет — значение этой конструкции превуалирует над другими.

    Ответить на этот комментарий
  3. Аня

    Когда читала анонс возможностей HTML 5, чуть слюнями не изошла — там обещалось много функций, которые ну просто давным-давно просились.

    Ответить на этот комментарий
  4. Княгиня (648 комментариев)

    Одним словом, дожить бы. И желательно прийти ко всем этим светлым будущим не инвалидом, рухнувшим под бременем настоящего. :)

    Ответить на этот комментарий
  5. Avatara (1 комментарий)

    Тоже ожидаем html5, черновая спецификация уже есть, ну и баги то же. Скажем, все проходит по валидации и стопорит в кодировку () Убираешь кодировку — Валидирует, но жалуется на отсутствие этой строчки. Замкнутый круг…

    Ответить на этот комментарий
  6. Иван (2 комментария)

    Хороший у Вас сайт! Все доспутно и понятно пишете. Так держать. И про доктайп узнал что-то новое. Спасибо!

    Ответить на этот комментарий
    • Княгиня (648 комментариев)

      На здоровье, заходите. :)

      Кстати, поскольку на сцену потихоньку выдвигается html5 со своим особым доктайпом, надо будет и его исследовать. Пока у меня нет уверенности, что ИЕ будет с ним корректно работать.

      Ответить на этот комментарий
  7. SelenIT (6 комментариев)

    Парочка уточнений: во-первых, DTD — это document type definition, лишь часть document type declaration-а. А во-вторых, что важнее, браузеры смотрят не на тип документа как таковой, а лишь пытаются угадать, какой из режимов рендеринга к данному документу применить. И во всех браузерах новее NS6 (включая IE6!) доктайпы HTML4.x Strict, XHTML1.0 Strict/XHTML1.1 и HTML5 включают один и тот же режим — максимальной поддержки стандартов, на какую данный браузер только способен. Поэтому сейчас многие гуру верстки используют доктайп HTML5 по принципу «если не видно разницы, зачем писать больше» (тем более что XML-подобный синтаксис в HTML5 тоже валидируется).

    С Transitional-доктайпами (HTML4.x и XHTML1.0) сложнее, потому что они включают в новых браузерах так называемый «almost standards mode», в котором не по стандарту ведут себя картинки в ячейках таблиц (а в Опере — еще и инлайн-блоки). Поэтому я считаю, что с ними лучше не связываться, чтобы не нарваться на неожиданность (хотя и в какой-то степени документированную). На мой взгляд, уж лучше пара ошибок формальной валидности, но самый стандартный режим рендеринга.

    Самое лучшее исследование вопроса, на мой взгляд — здесь: http://hsivonen.iki.fi/doctype/ (кстати, этот же автор написал парсер HTML5 для Firefox и для validator.nu).

    Еще немножко по теме я «накалякал» вот здесь: ссылка не работает :)

    Ответить на этот комментарий
    • Княгиня (648 комментариев)

      Вы-таки обратите внимание на дату моей заметки. На тот момент ФФ колебался между «два» и «полтора», Хрома и IE8 ещё не было в природе, а какая была Опера — не помню.

      Ответить на этот комментарий
      • SelenIT (6 комментариев)

        В «ФФ полтора-два» всё уже было «по-взрослому»: минималистичный доктайп HTML5 включал полностью стандартный режим, а Transitional-доктайпы — «почти стандартный».

        Статья-то хорошая и актуальная по сей день (о доктайпах и режимах и сегодня ходят странные и нелепые мифы и домыслы, и правдивая информация всегда «в тему»). Не зря она занимает первую строчку в «лучшем блога». Но если есть возможность слегка ее «осовременить» и дополнить новыми данными — будет замечательно вдвойне!

        Ответить на этот комментарий

Есть что сказать? Не молчим!

Используйте теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" code=""> <ul> <li> <ol> .

Комментарии короче 200 символов публикуются без активной ссылки. Пробелы не учитываются.

Ссылки с комментариев dofollow. Ознакомьтесь, пожалуйста, с правилами dofollow-комментирования. Кто не читает, тот сам себе враг.