Переключение режимов браузера с помощью Doctype

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

О чем эта статья

Здесь описывается переключение режимов применительно к Firefox и другим браузерам на движке Gecko, Safari и другим браузерам на движке WebKit, Opera, Konqueror, Internet Explorer для Mac, Internet Explorer для Windows и браузерам-надстройкам над IE. Вместо названий движков будем пользоваться названиями самого известного браузера на каждом движке.

Назвыания движков браузеров

BrowserEngineECMAScript Engine
Firefox, MozillaGeckoSpiderMonkey
Internet Explorer 4…7Tridentjscript
Mac IE 5Tasmanjscript
Opera 7…9.2Prestolinear_b
Opera 9.5Presto Core 2futhark
KonquerorKHTMLKJS
SafariWebKitJavaScriptCore

Статья посвящена механизму переключения режимов и не описывает поведение каждого режима в деталях.

Режимы

Ниже перечислены различные режимы современных браузеров:

Для страниц с типом контента text/html

Выбор режима для контента с типом text/html зависит от декларации doctype (подробности ниже). В IE8 режим зависит также от других факторов. Но по умолчанию даже в IE8 режим зависит от доктайпа (для не-интранет-сайтов, не внесенных в «черный список» Microsoft).

Внимание: поведение одноименных режимов у разных браузеров может отличаться (хотя в статье они описываются единообразно)!

Quirks Mode (режим обратной совместимости)

В Quirks mode браузеры намеренно нарушают современные спецификации веб-языков, чтобы страницы, написанные в манере конца 90-х, не разваливались. Разные браузеры воспроизводят разные причуды. IE6, 7 и 8 в Quirks mode фактически воспроизводят IE 5.5. У других браузеров Quirks mode — набор отклонений от «почти стандартного» режима.

Если вы пишете новые страницы, то от вас ждут соблюдения соотв. спецификаций (в частности, CSS2.1) и использования стандартного режима.

Standards Mode (стандартный режим)

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

HTML 5 называет этот режим «режимом без причуд» (no quirks mode).

Almost Standards Mode («почти стандартный», полустандартный режим)

У Firefox, Safari и Opera (начиная с 7.5) и IE8 есть и третий режим — «почти стандартный», при котором рисунки в ячейках таблицы выравниваются по вертикали традиционно (т.е. без текстовых отступов под ними — прим. перев.), а не в строгом соответствии со спецификацией CSS2. IE 6 и 7 для Windows, Opera ниже 7.5 и Konqueror не нуждаются в таком режиме, поскольку даже в своих стандартных режимах не соблюдают спецификации относительно выравнивания картинок в ячйках таблиц. Фактически, их стандартные режимы ближе к «почти стандартному» режиму Мозиллы, чем к ее стандартному режиму.

HTML 5 называет этот режим «режимом с ограниченными причудами» (limited quirks mode).

Режим IE7

У IE8 есть режим, в основном воспроизводящий стандартный режим IE7. У других браузеров подобных режимов нет, нет его и в спецификации HTML5.

Для страниц с типом контента application/xhtml+xml (XML-режим)

В Firefox, Safari и Opera HTTP-заголовок Content-Type:application/xhtml+xml (но не Doctype и не элемент meta!) включает XML-режим. В нем эти браузеры обрабатывают XML-документы в соответствии со спецификацией (в той мере, в какой она в них реализована).

IE6, 7 и 8, равно как Mac IE5, не поддерживают application/xhtml+xml в принципе.

В браузере Nokia S60, основанном на движке WebKit, application/xhtml+xml не включает XML-режим, ради совместимости с синтаксически некорректным мобильным контентом (старые мобильные браузеры не использовали настоящего XML-парсера, поэтому на специальных сайтах для мобильников может встречаться некорректный XML).

Что происходит с такими страницами в Konqueror, автор пока не выяснил.

Статья по теме:  В Вордпресс не работает кнопка добавить файл и многое другое

Режимы, не относящиеся к вебу

У некоторых движков также имеются режимы, не предназначенные для веб-контента. Здесь они упомянуты лишь «для коллекции». У Оперы есть режим WML 2.0. У WebKit на OS Leopard есть специальный режим для старых виджетов Dashboard.

Где и как это проявляется

Различие режимов проявляется в следующем:

Отображение

Режимы для text/html влияют главным образом на отображение CSS. Например, стили в таблице не наследуются — это «причуда», проявляющаяся только в Quirks mode. В некоторых браузерах в Quirks mode используется боксовая модель IE 5.5. Всех «причуд» отображения в одной статье не перечислить (наиболее удачная попытка, которую я смог найти, здесь — прим. перев.).

В «почти стандартном» режиме (в тех браузерах, у которых он есть) высота ячеек таблиц, содержащих одни рисунки, вычисляется иначе, чем в стандартном режиме.

В XML-режиме к HTML-элементу body не применяется ряд специальных правил (напр., его фон не распространяется на корневой элемент — прим. перев.) и CSS-селекторы становятся чувствительны к регистру.

Парсинг

Есть несколько «причуд», которые влияют на парсинг HTML и CSS, и могли бы помешать правильному парсингу корректных страниц. Такие причуды включаются и выключаются вместе с «причудами» отображения, т.е. с Quirks mode (насколько я знаю, их две основных, это комментарии с двойным дефисом и таблицы внутри <p> — прим. перев.). Однако, важно понимать, что противопоставление Quirks mode и Standards mode относится главным образом к парсингу и отображению CSS, а не к парсингу HTML.

Многие ошибочно считают стандартный режим «режимом строго парсинга», думая, что он заставляет браузеры считаться с правилами синтаксиса HTML и что браузеры в нем способны оценивать правильность разметки. Ничего подобного. Браузеры пытаются исправлять «теговый суп» даже тогда, когда действует стандартный режим отображения (в 2000-м, до выхода Netscape 6, у Мозиллы действительно были режимы парсера с принудительной проверкой синтаксиса, но они оказались несовместимы с суровой действительностью и от них пришлось отказаться).

Другое распространенное заблуждение связано с парсингом XHTML. Многие считают, что само указание XHTML-ного Doctype меняет тип парсинга. Это не так. XHTML-документы, отданные сервером как text/html, разбираются тем же парсером «тегового супа», что и HTML. С точки зрения браузеров, такой XHTML — всего лишь «суп из тегов с гренками» (лишними слешами там и сям).

Лишь документы, отданные с XML-ным Content-type (напр., «application/xhtml+xml» или «application/xml») включают XML-режим парсинга, правила которого полностью отличаются от HTML-ного.

Скрипты

Хотя «причуды» Quirks mode касаются главным образом CSS, у скриптов бывают свои «причуды». Например, у Firefox в Quirk mode можно обращаться к элементам по id, как к глобальным переменным (как это сделано в IE). Влияние смены режимов в скриптах в IE8 заметнее, чем в других браузерах.

В XML-режиме некоторые интерфейсы DOM ведут себя в корне по-другому, потому что поведение DOM API для XML). было задумано как несовместимое с таковым для HTML.

Doctype как переключатель режимов, или «вынюхивание Doctype» (в оригинале «Doctype Sniffing» — прим. перев.)

Все современные браузеры ориентируются на Doctype (или его отсутствие) в начале страницы, выбирая режим отображения для документов типа text/html. К документам, отданным сервером с XML-ным Content-type, это не относится.

Объявление типа документа (Doctype) — это синтаксический пережиток SGML, исторического фреймворка для описания языков разметки, на котором был основан HTML до появления HTML5 (который лишь похож на SGML, но не основан на нем). В спецификации HTML 4.01 сказано, что объявление типа документа нужно для получения информации о версии HTML. Но несмотря на название «объявление типа документа» и несмотря на то, что говорит спецификация HTML 4.01, объявление типа документа — не самое подходящее средство для проверки принадлежности SGML- или XML-документа к определенному типу, хотя, казалось бы, именно для этого оно и придумано (судя по названию). Более подробно об этом — в конце статьи.

Ни спецификация HTML 4.01, ни стандарт ISO 8879 (SGML) ничего не говорят об использовании Doctype в качестве переключателя режимов отображения. «Вынюхивание Doctype» основано на наблюдении, что подавляющее большинство документов с «причудами» на тот момент либо не имели Doctype, либо содержали в нем ссылки на устаревшие DTD. HTML5 признает эту реальность и определяет doctype только для страниц типа text/html, и исключительно для переключения режима.

Статья по теме:  Оптимизация верстки под Retina-дисплеи

Типичное объявление типа документа (до появления HTML5) состояло из строки «<!DOCTYPE», имени корневого элемента («HTML»), строки «PUBLIC», публичного идентификатора DTD в кавычках, возможно — системного идентификатора (URL) этого же DTD и символа «>». Doctype размещается в документе до открывающего тега корневого элемента.

Выбор Doctype

text/html

Простые советы по выбору Doctype для новых документов, отдаваемых сервером как text/html
Cтандартный режим, валидация по «последнему слову техники»

<!DOCTYPE html>

Это лучший вариант, если вам нужна валидность новшеств типа <video>, <canvas> и ARIA. Учтите, что определение валидности HTML5 еще не устоялось. И обязательно проверяйте выравнивание рисунков в таблицах в Firefox, Safari, Chrome, Opera 9 или 10. Тестирование его в IE не даст адекватного результата (хотя в IE8 проверить тоже надо)!

Cтандартный режим, валидация по устоявшейся схеме

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

Этот доктайп тоже включает стандартный режим, определение валидности 10-летнего «старичка» HTML4.01 стабильнее некуда. Но тоже обязательно проверяйте выравнивание рисунков в таблицах в Firefox, Safari, Chrome, Opera 9 или 10. Тестирование его в IE не даст адекватного результата (хотя в IE8 проверить тоже надо)!

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

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

Это даст вам «почти стандартный» режим (и полностью стандартный в ископаемых версиях Мозиллы). Но учтите, что дизайны на основе разрезанных картинок в таблице могут поломаться, если вы позже перейдете на HTML5 (т.е. полностью стандартный режим).

Вы осознанно хотите получить Quirks mode

Не ставить Doctype.

Пожалуйста, не делайте этого. Верстка для Quirks mode начнет преследовать вас, ваших коллег или будущих сменщиков — когда никто больше не будет думать о совместимости с IE 5 (как уже никому нет дела до Netscape 4.x). Верстка для Quirks mode — плохая идея, искренне убеждает автор статьи.

Если вам еще нужна поддержка Windows IE 6, лучше воспользоваться условными комментариями, чем отбрасывать остальные браузеры назад, в режим обратной совместимости.

Автор не рекомендует XHTML-доктайпы, потому что отдача XHTML как text/html признана вредной. Если вы все-таки выберете XHTML-доктайп, не забывайте, что XML-декларация заставляет IE 6 (но не IE 7!) переключиться в Quirks mode.

application/xhtml+xml

Самое простое правило, которое можно предложить для страниц, отдаваемых как application/xhtml+xmlне использовать Doctype вообще. Страницы при этом, правда, не будут считаться «строго соответствующими» стандарту XHTML 1.0, но на практике это не имеет значения (см. дополнение ниже).

Сложности с IE8

У IE8 четыре режима: режим причуд IE5.5, стандартный режим IE7, «почти стандартный» режим IE8 и стандартный режим IE8.

Выбор режима определяется данными разных источников: доктайпом, метатегом, HTTP-заголовком, периодически скачиваемыми от Microsoft данными, интранет-зоной, пользовательскими настройками, настройками интранета и интерфейсной кнопкой, нажимаемой/отжимаемой пользователем (а в др. приложениях, использующих движок IE8, режим зависит еще и от настроек приложения).

Хорошая новость в том, что IE8 определяет режим «вынюхиванием доктайпа», как другие браузеры, если:

  • Сайт не посылает HTTP-заголовка X-UA-Compatible.
  • Автор сайта не указал метатега X-UA-Compatible.
  • Microsoft не внес доменное имя сайта в <a href=«//philip.html5.org/data/ie8-compat-urls.txt»>«черный список»

Админ интранета не внес сайт в «черный список».Пользователь не нажал кнопку Compatibility View (или иным путем не внес домен в свой пользовательский«черный список»).Сайт не в интранете.Пользователь не включил опцию «отображать все сайты как IE7».
В перечисленных случаях (кроме двух пунктов с X-UA-Compatible) IE8 реагирует на доктайп как IE7. Эмуляция IE7 называется Compatibility View.

В случаях X-UA-Compatible, IE8 ведет себя полностью иначе по сравнению с др. браузерами. См. приложение в оригинале статьи или диаграммы (//hsivonen.iki.fi/doctype/ie8-mode.pdf, //hsivonen.iki.fi/doctype/ie8-mode.png).

К сожалению, без HTTP-заголовка или метатега X-UA-Compatible, IE8 позволяет пользователю случайно сбросить ваш сайт из стандартного режима IE8 в режим эмуляции IE7, даже с правильным доктайпом. Хуже того, это может сделать и админ интранета. Кроме того, Microsoft может внести в «черный список» весь ваш домен (напр. mit.edu)!

Чтобы бороться с этим, доктайпа недостаточно, нужен HTTP-заголовок или метатег X-UA-Compatible

Простые советы по выбору HTTP-заголовка или метатегаX-UA-Compatible для новых документов типа text/html, у которых уже есть доктайп, включающий стандартный или «почти стандартный» режим в других браузерах:

Ваш домен не попал в «черный список» Microsoft и для вас важнее отсутствие браузероспецифичных костылей, чем гарантия того, что пользователи не получат сайт в режиме IE7

Вам не нужен HTTP-заголовок или метатег X-UA-Compatible.

Ваш домен попал в «черный список» Microsoft, на вашем домене (как на iki.fi!) есть сайты других авторов, из-за которых пользователи могут включать Compatibility View для всего домена или вы хотите гарантии, что пользователь не включит Compatibility View для вашего сайта

Либо включите в страницу следующий элемент meta (что невалидно в HTML5): <meta http-equiv="X-UA-Compatible" content="IE=Edge">, либо установите следующий HTTP-заголовок: X-UA-Compatible: IE=Edge

Ваш сайт работал в IE7, но ломается в IE8

Сначала либо включите в страницу следующий элемент meta (что невалидно в HTML5): <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">, либо установите следующий HTTP-заголовок: X-UA-Compatible: IE=EmulateIE7

Затем исправьте сайт, чтобы он не зависел от нестандартного поведения IE7, и перейдите на IE=Edge.

Ссылки по теме

Статья по теме:  Декларация !important в CSS

Дополнение: обращение к разработчикам реализаций и авторам спецификаций, работающим с XML

Пожалуйста, не переносите «вынюхивание Doctype» в XML.

«Вынюхивание Doctype» — это решение проблемы «тегового супа», на уровне этого же «супа». Оно было придумано уже после спецификаций HTML 4 и CSS2, как эвристический способ разграничить «наследия дикого веба» от документов, чьи авторы рассчитывают на стандартное поведение.

Иногда возникают предложения, что «вынюхивание Doctype» может применяться и в XML-среде для выбора различных обработчиков, распознавания используемого словаря или включения/выключения каких-то «фич». Это плохая идея. Раздача обработчикам и активация словаря должны основываться на пространствах имен, а активация «фич» — на явных инструкциях обработки или элементах.

Вся концепция «well-formedness» была введена, чтобы сделать возможными парсинг XML без участия DTD и, более того, документы без Doctype. C формальной точки зрения, если два XML-документа имеют одну каноническую форму и приложение обрабатывает их по-разному (причем различие не вызвано намеренным отключением обработки внешних сущностей), то, вероятно, это приложение «глючит». С практической точки зрения, если ContentHandler из SAX2 «видит» два XML-документа как одинаковый контент, а приложение воспринимает их по-разному, то оно тоже скорее всего «глючит». Поскольку вы, как автор веб-страницы, не можете гарантировать, что каждый, кто парсит вашу страницу, использует XML-процессор с распознаванием внешних сущностей (даже если в некоторых браузерах это и так), вставка Doctype в XML для веба практически бессмысленна, и делается зачастую просто по привычке или «священному ритуалу». И без Doctype можно провалидировать страницу по DTD, используя функцию перекрытия DTD у валидатора от W3C, а еще лучше воспользоваться валидацией на базе RELAX NG, которая не засоряет документ ссылками на схемы. Требование наличия доктайпа только для различения чего-либо нелепо, хотя именно таково положение дел с HTML.

Кроме того, когда низкоуровневая спецификация указывает, что две вещи эквивалентны, спецификация более высокого уровня не должна пытаться придать этим вещам разное значение. Рассмотрим <!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Strict//EN» «//www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd»>. Если убрать публичный идентификатор, ссылка будет по-прежнему указывать на то же DTD и, значит, Doctype <!DOCTYPE html SYSTEM «//www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd»> значит то же самое, что и предыдущий. Должны ли они «вынюхиваться» по-разному? Мысль можно развить еще дальше. Предположим, DTD скопировано на example.com под именем foobar.dtd: <!DOCTYPE html SYSTEM «//example.com/foobar.dtd»>. Как должно распознаваться это? Смысл ведь тот же. Наконец, DTD может быть вообще целиком вставлено внутрь Doctype!

Еще аналогия: если в программе написано #include "foo.h", не надо привязывать никакой черной магии к имени foo.h, т.к. всегда можно скопировать его содержимое в саму программу, либо переименовать в bar.h и написать #include "bar.h".

Для HTML и SGML такой спор не имеет смысла, т.к. браузеры не используют настоящих SGML-парсеров.


Понравилась статья? Поделиться с друзьями: