Коробка с cюрпризами

Сначала мы боялись, потом вроде взяли себя в руки, приняв происходящее за простые и понятные фокусы. Сегодня пришло время удивляться снова — фокусы IE8 с переключением режимов рендеринга оказались хитрее, чем казалось поначалу. Что же мы знаем про магическую директиву X-UA-Compatible?

Давайте проверим, скормив IE8 простой документ:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
<head>
    <title>IE=x</title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=x"/>
    <style type="text/css">
        BODY[class*='page'] {
            background:#090; /* IE8 и прочие современные */
            }
        *:first-child+HTML .page {
            background:#FC0; /* IE7, исключительно */
            }
        * HTML .page {
            background:#C00; /* IE6 и младше */
            }
    </style>
</head>
<body class="page"></body>
</html>

Меняя значение IE=x последовательно — 8, 7, 6 — мы переключаем режимы рендеринга IE и получаем такой светофор. Красивую расцветку обеспечили нам специальные CSS-фильтры для каждой версии IE:

Ну что — пока без сюрпризов, почти скучно. А давайте-ка подключим к документу фавиконку. Вставим её куда-нибудь в элемент <head>, произвольно:

<head>
    <title>IE=x</title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    <link rel="shortcut icon" type="image/x-icon" href="favicon.ico"/>
    <meta http-equiv="X-UA-Compatible" content="IE=x"/>
</head>

…и вот здесь начинается самое интересное — все документы позеленели, при любых значениях IE=x. И это фактически означает то, что IE8 просто перестал воспринимать директиву X-UA-Compatible.

Нет, дело совсем не в фавиконке. Дело в новом расположении элемента <meta> с нашей чудо-директивой. Теперь мета-информация о режиме рендеринга документа становится известна после появления первых элементов самого документа и успешно игнорируется.

В ходе тестов выяснилось, что предшествовать директиве могут только мета-элементы и <title> — по сути тоже часть мета-описания документа. Все остальные варианты расположения директивы делают её абсолютно неработоспособной.

Эксперименты это конечно хорошо, но хочется знать наверняка, поэтому полчаса копания в MSDN дали однозначный ответ в статье «Defining Document Compatibility» — все предположения оказались верны:

Являясь регистронезависимым, заголовок X-UA-compatible, тем не менее, должен находиться в секции HEAD страницы перед всеми остальными элементами, за исключением title и других мета-элементов.

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

Комментарии

17

Вадим, спасибо за статью!
Исправьте, пожалуйста, в примере незакрытый тег :)

Немного не в тему, но может кому-то поможет в будущем.
Заметил такую вещь, характерную для семейства IE.
Если в обычном CSS файле задать у любого элемента свойство background

#sample{
background:url(../img/sample.gif)top left repeat-x;
}

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

#sample{
background:url(../img/sample.gif) top left repeat-x;
}

А если не указывать директиву, то движок будет от ie8 ? Если это так и например мне нужен именно такой режим, то можно тогда не указывать эту директиву?

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

@stolho: С пробелами в css IE вообще своеобразно обходится. Так что тоже желательно ставить их везде, где не запрещено, имхо. Хуже не будет, а от необходимости помнить о потенциальных траблах самообороняемся.

всегда ставим все мета-теги до тайтла…

Вот-вот, именно поэтому при тестировании и не напарывался на эту проблему — аккуратизм и последовательность помогли )

это напоминает глюк с доктайпом в IE6. прям родовое проклятие Майкрософт ;)

Исторически сложилось, что IE7 не приходится хакать, поэтому на уме был какой-то древний пример )

Pepelsbey, давно читаю ваш блог, и вы не перестаете радовать.

После прочтения статьи взял за правило вставлять в шапку страницы такой код

<meta http-equiv="X-UA-Compatible" content="EmulateIE7"/>

после чего правлю верстку под ie6-7 и не заморачиваюсь с отображением под ie8.

Спасибо автору. Сразу же после прочтения заточил свои шаблоны под ие8.

Спасибо, учитывая то что IE8 взломали за первый же день......тут нечему и удивляться, как ни обещали Microsoft конфетку так и не слепили...