Время для прочтения: 2 мин. 25 сек.

Избавляемся от CSS хаков в Internet Explorer

Большинство вебмастеров - разработчиков сегодня делятся на два лагеря: первые предпочитают условные комментарии для отделения версий Internet Explorer друг от друга, вторые - CSS хаки.

Я не отношусь ни к одной из перечисленных групп. И вот почему.

Любители условных комментариев делают примерно так:



<link rel="stylesheet" type="text/css" href="style.css" />
<!--[if IE 7]><link rel="stylesheet" type="text/css" href="ie7.css"  />< ![endif]-->
<!--[if IE 6]><link rel="stylesheet" type="text/css" href="ie6.css"  />< ![endif]-->

Сразу возникает несколько проблем:

  • Создаются лишние HTTP запросы
  • Пока браузер не получит содержимое файлов в условных комментариях, загрузка документа не продолжится
  • CSS правила получаются разбросанными по нескольким файлам, что затрудняет их поддержку и дальнейшую доработку

Любители же CSS хаков поступают проще:


div.foo {
    float: left;
    margin-left: 10px;
    _margin-left: 5px;
}

В данном подходе также имеются свои недостатки:

  • Код получается невалидным
  • Хаки основаны на неверной интерпретации браузером правил CSS (т. е. они заведомо «ошибочны»)
  • Никто не знает чем обернется их использование в дальнейшем

Что делаю я?

Я использую симбиоз этих двух вариантов в таком виде:

HTML:


<!doctype html> 
<!--[if lt IE 7]><html class="ie ie6 lte9 lte8 lte7"><![endif]-->
<!--[if IE 7]><html class="ie ie7 lte9 lte8 lte7"><![endif]-->
<!--[if IE 8]><html class="ie ie8 lte9 lte8"><![endif]-->
<!--[if IE 9]><html class="ie ie9 lte9"><![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--><html class=""><!--<![endif]-->
<head>
...

CSS:


div.bar {
    width: 300px;
}
.ie6 div.bar {
    width: 310px;
}
.ie7 div.bar {
    width: 290px;
}

Преимущества данного подхода очевидны:

  • Нет лишних запросов к серверу
  • Все стили структурированы и находятся в одном файле
  • Валидный и понятный код
  • Четкое разделение версий Internet Explorer
  • Метод совместим с WordPress, Dojo, Modernizr

Ссылки

Для вставки кода используйте HTML-теги
<pre><code class="php">ваш код</code></pre>

  • Алена Площенко

    Спасибо! Очень помогло

  • Yourick

    «Клиентская оптимизация придумана не просто так и один запрос может уничтожить все ваши старания» — то есть 50 запросов пройдут нормально, а вот именно этот несчастный ie6.css размером 5кБ уложит клиента наповал? Что это за «пользователи GPRS», использующие IE6? Не пугайте вы молодых разработчиков, они ж это за чистую монету принимают. Дались вам эти запросы.
    В описанном методе тоже вполне себе имеются недостатки. Во-первых, правила, написанные таким образом, сильно увеличат размер документа. Зачем скармливать всем браузерам бесполезный код, нужный только IE6-7? Зачем держать этот мусор в главном файле? Во-вторых, .ie6 div.bar — это добавление лишнего каскада, что в случае сложного макета может привести к конфликту правил.
    В общем, делайте выводы сами. Я голосую за отдельный файл, подключенный через условные комментарии.

    • На вкус и цвет, как говорится … все фломастеры разные 🙂
      Полистайте на досуге webo.in — там достаточно полезного материала с разъяснениями на тему оптимизации.

    • Посмотрите статистику! 80% населения (Украины) до сих пор сидят на ИЕ6!!!!
      Наплюйте на них — завтра наплюют на ваш сайт!
      Не все живут в столицах и имеют выделенку и супер-комп.
      Я всегда проверяю работу на ИЕ6.
      И этот метод — супер!

  • Newman

    Следует также учитывать то, что иногда требуется исключить некоторое свойство CSS для старых браузеров ie, и оставить его для более новых, а также для прочих браузеров.

    К примеру свойство min-height IE7 обрабатывает не корректно, в отличии от последующих версий IE и прочих браузеров. Поэтому я доработал ваш пример, добавив классы ‘not_*‘:

    [html]
    <!—[if lt IE 7]<body class="ie ie6 lte9 lte8 lte7">[endif]—>
    <!—[if IE 7]<body class="ie ie7 lte9 lte8 lte7 not_lte6">[endif]—>
    <!—[if IE 8]<body class="ie ie8 lte9 lte8 not_lte6 not_lte7">[endif]—>
    <!—[if IE 9]<body class="ie ie9 lte9 not_lte6 not_lte7 not_lte8">[endif]—>
    <!—[if gt IE 9]<body class="ie not_lte6 not_lte7 not_lte8 not_lte9">[endif]—>
    <!—[if !IE]<body class="not_ie not_lte6 not_lte7 not_lte8 not_lte9">[endif]—>
    [/html]

    Теперь свойство min-height достаточно вставить в класс not_lte7 и ie6 и 7 будут его игнорировать, а остальные корректно обрабатывать.

    • Спасибо. Поправил ваш комментарий, думаю, он многим будет полезен.

    • Путник

      Как говорил Тёма, так верстают только М…

  • Айрат

    ничего страшного не произойдет если еще несколько http запросов
    обработает сервер такова условия которые ставит ишак ie

    да и как же на этот код смотрит валидатор стандартов

    • Клиентская оптимизация придумана не просто так и один запрос может уничтожить все ваши старания (не забывайте про пользователей GPRS). Прежде чем так говорить, прочтите хотя бы статьи на webo.in. Зачем вам 6 файлов под ИЕ, когда можно обойтись одним? Валидатор на этот код смотрит без вопросов, что нельзя сказать про разного рода хаки.

  • Сергей

    Настоящий Ноу-хау !
    Всё чётко и грамотно изложено.
    Пошёл пробовать…