Кросс-браузерный CSS
Кросс-браузерный CSS
Сколько ни разрабатывали стандарты, сколько ни напрягался небезызвестный консорциум W3, сколько ни ругали разработчиков софта недовольные разработчики сайтов — все равно поддержка CSS в браузерах реализована криво и не полностью (за исключением MSIE 5.5 под Macintosh и Netscape 6.0). Начиная с третьих версий массовых браузеров, у веб-мастеров прибавилось головной боли. И эта боль вызвана разной реализацией CSS у разных браузеров. Более того, эта реализация в Netscape 4.x настолько корявая, что список багов занимает 4 страницы мелким шрифтом без подробного описания.
Возникает вопрос: что же делать бедным веб-мастерам? Вариантов несколько:
1. Забыть про CSS и вообще его не использовать (совершенно непривлекательный вариант, потому как CSS на самом деле вещь полезная во многих отношениях и отказываться от полезного инструмента глупо);
2. Свести использование CSS к минимуму, чтобы быть на 100% уверенным в одинаковости (более-менее приемлемое решение, но сгодится только как временное, потому что через годик-другой без CSS не обойдется ни один приличный сайт, а табличная верстка уйдет в небытие);
3. Разобраться в CSS и ограничить себя применимостью одной таблицы стилей ко всем браузерам (это один из хороших вариантов, но весьма ограничивает возможности использования всех богатств и достоинств CSS);
4. Детально разобраться в CSS и использовать фишки, скрывающие фрагменты кода от некоторых браузеров, добиваясь максимальной эффективности от каждого конкретного браузера (хорошее решение, применимо во многих случаях);
5. Детально разобраться в CSS и писать разные таблицы стилей для разных браузеров (тоже хорошее решение).
Последние три пункта (в особенности 4-ый и 5-ый) собственно и относятся к кросс-браузерному CSS. Вот и остановимся на них поподробнее и начнем с самого легкого.
Одна таблица стилей для всех браузеров
Это простейший метод добиться того, чтобы ваша страничка выглядела одинаково во всех браузерах. Но этот метод весьма ограничивает возможности использования всех богатств и достоинств CSS. Например, вы лишитесь возможности использовать line-height или margin-top, потому что некоторые браузеры некорректно работают с этими элементами.
Список всех багов слишком обширен, поэтому ограничимся наиболее явными и опасными:
1. Не используйте margin-top;
2. Не используйте любые единицы измерения, кроме пикселей (px);
3. Не прописывайте высоту линии (line-height);
4. Не используйте ключевое слово normal (оно все равно не нужно);
5. Не используйте числовые значения для font: (weights) в сокращенной записи стилей для шрифта;
6. Устанавливйте margin-left и margin-right только для BODY и ни в коем случае для других тэгов;
7. Не используйте стили для LI, DD и DT.
В дополнение ко всему, если вы используете таблицы, надо разделить селекторы для BODY на две части: одни для наследующихся, другие для не наследующихся. Например:
BODY { font-family: sans-serif; color: red; background: white; margin-left: 7%; margin-right: 5%; margin-bottom: 2em }
Заменяется на
BODY { font-family: sans-serif; color: red } BODY { background: white; margin-left: 7%; margin-right: 5%; margin-bottom: 2em }
Затем для каждого блокового элемента, кроме LI, DD и DT, плюс SPAN прописать наследующиеся свойства. Например:
ADDRESS, BLOCKQUOTE, BODY, div, DL, H1, H2, H3, H4, H5, H6, OL, P, PRE, SPAN, UL {font-family: sans-serif; color: red}
Это надо сделать из-за IE 3 и Netscape 4, потому что когда они обрабатывают страницу и встречают таблицу, то частенько убивают наследование от тэга BODY для тэга TABLE и всех последующих тэгов.
Вот довольно краткая инструкция, но она поможет написать рабочую каскадную таблицу стилей, которую будут обрабатывать одинаково практически все браузеры, поддерживающие CSS.
Скрываем куски кода
Как спрятать кусок таблицы стилей от определенного браузера? Во-первых, разберемся, зачем это вообще надо. К примеру, вы используете какие-то элементы, которые неправильно интерпретируются Netscape 4. В этом случае пользователи этого глючного браузера увидят совсем не то, что вы планировали. Тогда можно написать простенькую таблицу стилей, которую правильно интерпретируют все браузеры, и вставить кусок кода, который будет скрыт от Netscape 4. Делается это так:
/* Это таблица стилей */ @import url(okbrowsers.css);
Код, который понимают все браузеры, находится между /* */, а все остальное запихивается в okbrowsers.css.
Конструкция @import url(okbrowsers.css) прячет файл okbrowsers.css от Netscape 4 и MSIE 3. Однако такое решение не всегда удовлетворительно, потому что в серьезных таблицах стилей надо учитывать особенности многих браузеров. Вот методы для различных браузеров.
Internet Explorer 3.0
1. Можно использовать несколько включений тэгом <LINK>, MSIE 3 проигнорирует все, кроме последнего, тогда как остальные браузеры обработают все.
<LINK rel="stylesheet" href= ="WillNotBeReadByIE3.css" type= ="text/css"> <LINK rel="stylesheet" href= ="awayie3.css" type="text/css">
То есть в файле awayie3.css должен содержаться CSS-код для MSIE 3, а в файле WillNotBeReadByIE3.css все остальное;
2. При наличии в названии класса или ID дефиса этот класс игнорируется IE 3;
3. Если после описания стилей идет тэг <LINK>, то браузер обработает только файл, прописанный в этом тэге;
<STYLE type="text/css"> /* Не распознается IE 3 */ </STYLE> <LINK rel="stylesheet" href= ="awayie3.css" type="text/css">
4. Если в коде встречается несколько объявления для одного и того же элемента, то IE 3 игнорирует все, кроме первого
P {color: red; font-size: 14pt} P {color: green}
В IE 3 цвет будет красным, потому что повторное объявление игнорируется, тогда как в остальных браузерах цвет будет зеленым. Поэтому для каждого глючного свойства в IE 3 можно иметь одно объявление (первое) для IE 3, а второе — для всех остальных браузеров:
BODY {color: black} BODY {color: white; background: black}
Если бы не было первой строчки, то возникла бы проблема, так как IE 3 не поддерживает background для BODY в таблицах стилей, встроенных через тэг <LINK> . Но в этом случае тот факт, что цвет — белый, не вызывает конфликтов с background, потому что IE 3 игнорирует color: white, а применяет color: black;
5. Можно использовать комментарий после селектора, тогда IE3 проигнорирует класс:
P/* комментарий */.class.
Internet Explorer 4
1. Если использовать строчный формат инструкции @import вместо формата url() format, то IE 4 проигнорирует это включение. Например @import "hiddenfromie4.css";
2. Можно вставить комментарий после свойства, например color/* */: red;
3. Если указать после @import источник вывода (например @import url(hiddenfromie4.css) screen), то IE 4 проигнорирует включение;
4. Если класс нужно включить только в IE 4, надо сделать так
P/* comment */.class {}.
Internet Explorer 5
1. Комментарий после свойства color/* */: red.
Opera
1. Добавить класс или ID к BODY, а потом это все вместе к селектору. Например BODY.class P {hidden};
2. Используйте класс или ID без различия прописных и строчных букв. Например <div id="body">, #Body P для того, чтобы скрыть это от Оперы;
3. Можно взять свойство в кавычки. Например color: "red";
4. Используйте открывающий тэг комментария SGML в той же линии, где находится селектор для того, чтобы скрыть эту строку от Оперы:
<!-- P {color: red} (перед селектором не должно быть перевода строки)
5. Пропустите # перед цветом, чтобы скрыть его от Оперы.
Netscape 4
1. Используйте !important — Netscape игнорирует эту инструкцию; к примеру, P {color: red!important} P {color: blue} будет синим в Netscape (и в IE 3, но по другой причине) и красным в IE 4-5 и Opera;
2. Заключать стили в @media all {} (или @media screen);
3. Если font-size задаете в пикселях, опустите px для скрытия от Netscape; например, font-size: 12;
4. Используйте обратный слэш для скрытия от Netscape — P \{ {color: red; background: green};
5. Включайте стили через @import — Netscape не поддерживает эту инструкцию;
6. Обозначьте таблицу стилей для media="all" (т.е., <LINK href="css.css" rel="stylesheet" type= ="text/css" media="all"> ;<STYLE type="text/css" media="all"> ) — это скроет стили от Netscape;
7. Описывайте стили, используя HTML селектор — Netscape не поддерживает его;
Данное описание фишек не претендует на полноту, однако здесь описаны наиболее простые и полезные приемы. Осталась последняя и довольно интересная часть проблемы кросс-браузерного CSS — различные таблицы стилей для каждого браузера.
Различные таблицы стилей для каждого браузера
Идея такая: пишите таблицы стилей для каждого браузера, в полной мере используя особенности, фишки и пр. каждого из них, а потом с помощью JavaScript в зависимости от браузера подключаете нужный css-файл. Кроме того, надо иметь в виду, что не у всех пользователей JavaScript включен, а потому надо бы иметь css-файлик, который подключается по умолчанию с выключенным JavaScript, и этот файлик должен содержать CSS, который понимается всеми браузерами.
Оставим в сторонке браузеры версии 3 (если кому-то ну очень интересно, особенность подключения css-файлов для этих браузеров смотреть здесь http://www.richinstyle.com/masterclass/crossbrowser.html#separate ). А для остальных подойдет вот такой скрипт:
/* (c) 2000 RichInStyle.com (www.richinstyle.com */ ua=navigator.userAgent; l='<LINK rel="stylesheet" type="text/css" href="'; c='.css"> '; if (ua.indexOf('IE 4')!=-1)do-cument.write(l+'ie4'+c); if (ua.indexOf('IE 5')!=-1)do-cument.write(l+'ie5'+c); if (ua.indexOf("Opera 5")!=-1)do-cument.write(l+'op5'+c); else if (ua.indexOf("compatible")==-1) { if (ua.indexOf("/4")!=-1)document.write(l+'nn4'+c); if (ua.indexOf("/5")!=-1)document.write(l+'nn5'+c); }
А темплейт HTML-странички будет выглядеть примерно вот таким образом:
<HTML> <HEAD> <!-Опционально --> <STYLE type="text/css"> </STYLE> <LINK rel="stylesheet" href= ="all.css" type="text/css"> <SCRIPT src="style.js" type= ="text/javascript"> </SCRIPT> <BODY bgcolor="#xxxxxx" text= ="#xxxxxx" alink="#xxxxxx" link= ="#xxxxxxx" vlink="#xxxxxx">
Есть вообще два различных способа для этих реализации стилей при таком разделении:
1. Запихать работающие стили в all.css и потом лишь модифицировать их в файлах op5.css, ie5.css и т.д.
2. Сделать каждую таблицу стилей полной.
На первый взгляд, первый способ лучше. Однако при детальном рассмотрении это оказывается не так. Например, если вы захотите поместить объявления color и font в all.css, а margin и padding — в css-файлы для каждого браузера, то это сделать проще. Однако нельзя включить все свойства (color, margin, padding font) в all.css, потому что баги вам житья не дадут. Приходим ко второму варианту.
Таким образом, если вам совершенно необходимо использовать особенности каждого браузера в полной мере, без разделения таблиц стилей не обойтись. Самый простой и наиболее часто употребляемый вариант — это когда надо разделить стили Opera 5, MSIE 5 и Netscape 4. Делается это так
<HEAD> <STYLE type="text/css"> @import url(style.css); </STYLE>
Не понимает Netscape 4 этой конструкции, так что пользуйтесь на здоровье.
Надеюсь, эта статья поможет вам разрешить многие проблемы, потому что CSS сейчас используют повсеместно, но с умом достаточно редко.
Михаил Дубаков,
по материалам сайта www.richinstyle.com
e-mail: firefalcon@tut.by
(c) компьютерная газета
Сколько ни разрабатывали стандарты, сколько ни напрягался небезызвестный консорциум W3, сколько ни ругали разработчиков софта недовольные разработчики сайтов — все равно поддержка CSS в браузерах реализована криво и не полностью (за исключением MSIE 5.5 под Macintosh и Netscape 6.0). Начиная с третьих версий массовых браузеров, у веб-мастеров прибавилось головной боли. И эта боль вызвана разной реализацией CSS у разных браузеров. Более того, эта реализация в Netscape 4.x настолько корявая, что список багов занимает 4 страницы мелким шрифтом без подробного описания.
Возникает вопрос: что же делать бедным веб-мастерам? Вариантов несколько:
1. Забыть про CSS и вообще его не использовать (совершенно непривлекательный вариант, потому как CSS на самом деле вещь полезная во многих отношениях и отказываться от полезного инструмента глупо);
2. Свести использование CSS к минимуму, чтобы быть на 100% уверенным в одинаковости (более-менее приемлемое решение, но сгодится только как временное, потому что через годик-другой без CSS не обойдется ни один приличный сайт, а табличная верстка уйдет в небытие);
3. Разобраться в CSS и ограничить себя применимостью одной таблицы стилей ко всем браузерам (это один из хороших вариантов, но весьма ограничивает возможности использования всех богатств и достоинств CSS);
4. Детально разобраться в CSS и использовать фишки, скрывающие фрагменты кода от некоторых браузеров, добиваясь максимальной эффективности от каждого конкретного браузера (хорошее решение, применимо во многих случаях);
5. Детально разобраться в CSS и писать разные таблицы стилей для разных браузеров (тоже хорошее решение).
Последние три пункта (в особенности 4-ый и 5-ый) собственно и относятся к кросс-браузерному CSS. Вот и остановимся на них поподробнее и начнем с самого легкого.
Одна таблица стилей для всех браузеров
Это простейший метод добиться того, чтобы ваша страничка выглядела одинаково во всех браузерах. Но этот метод весьма ограничивает возможности использования всех богатств и достоинств CSS. Например, вы лишитесь возможности использовать line-height или margin-top, потому что некоторые браузеры некорректно работают с этими элементами.
Список всех багов слишком обширен, поэтому ограничимся наиболее явными и опасными:
1. Не используйте margin-top;
2. Не используйте любые единицы измерения, кроме пикселей (px);
3. Не прописывайте высоту линии (line-height);
4. Не используйте ключевое слово normal (оно все равно не нужно);
5. Не используйте числовые значения для font: (weights) в сокращенной записи стилей для шрифта;
6. Устанавливйте margin-left и margin-right только для BODY и ни в коем случае для других тэгов;
7. Не используйте стили для LI, DD и DT.
В дополнение ко всему, если вы используете таблицы, надо разделить селекторы для BODY на две части: одни для наследующихся, другие для не наследующихся. Например:
BODY { font-family: sans-serif; color: red; background: white; margin-left: 7%; margin-right: 5%; margin-bottom: 2em }
Заменяется на
BODY { font-family: sans-serif; color: red } BODY { background: white; margin-left: 7%; margin-right: 5%; margin-bottom: 2em }
Затем для каждого блокового элемента, кроме LI, DD и DT, плюс SPAN прописать наследующиеся свойства. Например:
ADDRESS, BLOCKQUOTE, BODY, div, DL, H1, H2, H3, H4, H5, H6, OL, P, PRE, SPAN, UL {font-family: sans-serif; color: red}
Это надо сделать из-за IE 3 и Netscape 4, потому что когда они обрабатывают страницу и встречают таблицу, то частенько убивают наследование от тэга BODY для тэга TABLE и всех последующих тэгов.
Вот довольно краткая инструкция, но она поможет написать рабочую каскадную таблицу стилей, которую будут обрабатывать одинаково практически все браузеры, поддерживающие CSS.
Скрываем куски кода
Как спрятать кусок таблицы стилей от определенного браузера? Во-первых, разберемся, зачем это вообще надо. К примеру, вы используете какие-то элементы, которые неправильно интерпретируются Netscape 4. В этом случае пользователи этого глючного браузера увидят совсем не то, что вы планировали. Тогда можно написать простенькую таблицу стилей, которую правильно интерпретируют все браузеры, и вставить кусок кода, который будет скрыт от Netscape 4. Делается это так:
/* Это таблица стилей */ @import url(okbrowsers.css);
Код, который понимают все браузеры, находится между /* */, а все остальное запихивается в okbrowsers.css.
Конструкция @import url(okbrowsers.css) прячет файл okbrowsers.css от Netscape 4 и MSIE 3. Однако такое решение не всегда удовлетворительно, потому что в серьезных таблицах стилей надо учитывать особенности многих браузеров. Вот методы для различных браузеров.
Internet Explorer 3.0
1. Можно использовать несколько включений тэгом <LINK>, MSIE 3 проигнорирует все, кроме последнего, тогда как остальные браузеры обработают все.
<LINK rel="stylesheet" href= ="WillNotBeReadByIE3.css" type= ="text/css"> <LINK rel="stylesheet" href= ="awayie3.css" type="text/css">
То есть в файле awayie3.css должен содержаться CSS-код для MSIE 3, а в файле WillNotBeReadByIE3.css все остальное;
2. При наличии в названии класса или ID дефиса этот класс игнорируется IE 3;
3. Если после описания стилей идет тэг <LINK>, то браузер обработает только файл, прописанный в этом тэге;
<STYLE type="text/css"> /* Не распознается IE 3 */ </STYLE> <LINK rel="stylesheet" href= ="awayie3.css" type="text/css">
4. Если в коде встречается несколько объявления для одного и того же элемента, то IE 3 игнорирует все, кроме первого
P {color: red; font-size: 14pt} P {color: green}
В IE 3 цвет будет красным, потому что повторное объявление игнорируется, тогда как в остальных браузерах цвет будет зеленым. Поэтому для каждого глючного свойства в IE 3 можно иметь одно объявление (первое) для IE 3, а второе — для всех остальных браузеров:
BODY {color: black} BODY {color: white; background: black}
Если бы не было первой строчки, то возникла бы проблема, так как IE 3 не поддерживает background для BODY в таблицах стилей, встроенных через тэг <LINK> . Но в этом случае тот факт, что цвет — белый, не вызывает конфликтов с background, потому что IE 3 игнорирует color: white, а применяет color: black;
5. Можно использовать комментарий после селектора, тогда IE3 проигнорирует класс:
P/* комментарий */.class.
Internet Explorer 4
1. Если использовать строчный формат инструкции @import вместо формата url() format, то IE 4 проигнорирует это включение. Например @import "hiddenfromie4.css";
2. Можно вставить комментарий после свойства, например color/* */: red;
3. Если указать после @import источник вывода (например @import url(hiddenfromie4.css) screen), то IE 4 проигнорирует включение;
4. Если класс нужно включить только в IE 4, надо сделать так
P/* comment */.class {}.
Internet Explorer 5
1. Комментарий после свойства color/* */: red.
Opera
1. Добавить класс или ID к BODY, а потом это все вместе к селектору. Например BODY.class P {hidden};
2. Используйте класс или ID без различия прописных и строчных букв. Например <div id="body">, #Body P для того, чтобы скрыть это от Оперы;
3. Можно взять свойство в кавычки. Например color: "red";
4. Используйте открывающий тэг комментария SGML в той же линии, где находится селектор для того, чтобы скрыть эту строку от Оперы:
<!-- P {color: red} (перед селектором не должно быть перевода строки)
5. Пропустите # перед цветом, чтобы скрыть его от Оперы.
Netscape 4
1. Используйте !important — Netscape игнорирует эту инструкцию; к примеру, P {color: red!important} P {color: blue} будет синим в Netscape (и в IE 3, но по другой причине) и красным в IE 4-5 и Opera;
2. Заключать стили в @media all {} (или @media screen);
3. Если font-size задаете в пикселях, опустите px для скрытия от Netscape; например, font-size: 12;
4. Используйте обратный слэш для скрытия от Netscape — P \{ {color: red; background: green};
5. Включайте стили через @import — Netscape не поддерживает эту инструкцию;
6. Обозначьте таблицу стилей для media="all" (т.е., <LINK href="css.css" rel="stylesheet" type= ="text/css" media="all"> ;<STYLE type="text/css" media="all"> ) — это скроет стили от Netscape;
7. Описывайте стили, используя HTML селектор — Netscape не поддерживает его;
Данное описание фишек не претендует на полноту, однако здесь описаны наиболее простые и полезные приемы. Осталась последняя и довольно интересная часть проблемы кросс-браузерного CSS — различные таблицы стилей для каждого браузера.
Различные таблицы стилей для каждого браузера
Идея такая: пишите таблицы стилей для каждого браузера, в полной мере используя особенности, фишки и пр. каждого из них, а потом с помощью JavaScript в зависимости от браузера подключаете нужный css-файл. Кроме того, надо иметь в виду, что не у всех пользователей JavaScript включен, а потому надо бы иметь css-файлик, который подключается по умолчанию с выключенным JavaScript, и этот файлик должен содержать CSS, который понимается всеми браузерами.
Оставим в сторонке браузеры версии 3 (если кому-то ну очень интересно, особенность подключения css-файлов для этих браузеров смотреть здесь http://www.richinstyle.com/masterclass/crossbrowser.html#separate ). А для остальных подойдет вот такой скрипт:
/* (c) 2000 RichInStyle.com (www.richinstyle.com */ ua=navigator.userAgent; l='<LINK rel="stylesheet" type="text/css" href="'; c='.css"> '; if (ua.indexOf('IE 4')!=-1)do-cument.write(l+'ie4'+c); if (ua.indexOf('IE 5')!=-1)do-cument.write(l+'ie5'+c); if (ua.indexOf("Opera 5")!=-1)do-cument.write(l+'op5'+c); else if (ua.indexOf("compatible")==-1) { if (ua.indexOf("/4")!=-1)document.write(l+'nn4'+c); if (ua.indexOf("/5")!=-1)document.write(l+'nn5'+c); }
А темплейт HTML-странички будет выглядеть примерно вот таким образом:
<HTML> <HEAD> <!-Опционально --> <STYLE type="text/css"> </STYLE> <LINK rel="stylesheet" href= ="all.css" type="text/css"> <SCRIPT src="style.js" type= ="text/javascript"> </SCRIPT> <BODY bgcolor="#xxxxxx" text= ="#xxxxxx" alink="#xxxxxx" link= ="#xxxxxxx" vlink="#xxxxxx">
Есть вообще два различных способа для этих реализации стилей при таком разделении:
1. Запихать работающие стили в all.css и потом лишь модифицировать их в файлах op5.css, ie5.css и т.д.
2. Сделать каждую таблицу стилей полной.
На первый взгляд, первый способ лучше. Однако при детальном рассмотрении это оказывается не так. Например, если вы захотите поместить объявления color и font в all.css, а margin и padding — в css-файлы для каждого браузера, то это сделать проще. Однако нельзя включить все свойства (color, margin, padding font) в all.css, потому что баги вам житья не дадут. Приходим ко второму варианту.
Таким образом, если вам совершенно необходимо использовать особенности каждого браузера в полной мере, без разделения таблиц стилей не обойтись. Самый простой и наиболее часто употребляемый вариант — это когда надо разделить стили Opera 5, MSIE 5 и Netscape 4. Делается это так
<HEAD> <STYLE type="text/css"> @import url(style.css); </STYLE>
Не понимает Netscape 4 этой конструкции, так что пользуйтесь на здоровье.
Надеюсь, эта статья поможет вам разрешить многие проблемы, потому что CSS сейчас используют повсеместно, но с умом достаточно редко.
Михаил Дубаков,
по материалам сайта www.richinstyle.com
e-mail: firefalcon@tut.by
(c) компьютерная газета
Компьютерная газета. Статья была опубликована в номере 25 за 2001 год в рубрике программирование :: разное