Вадим Макеев, Opera Software
http://msdn.microsoft.com/en-us/library/ms537512%28v=vs.85%29.aspx
Технология Microsoft предназначенная для управления загрузкой ресурсов HTML/CSS/JS.
Расширенное использование HTML-комментариев, добавлением дополнительного синтаксиса и логики.
Первое внедрение — IE 5.5. Последнее — IE9.
Условное состояние формируется на основе Expression внутри HTML-комментария: оператор, функция, значение «и/или».
Expression является индикатором необходимости интерпретации или игнорирования содержимого блока комментария.
Деление браузеров на типы:
Виды Conditional Comments:
<![if expression]> HTML <![endif]>
<!--[if expression]> HTML <![endif]-->
<!-- Comment content -->
Функции:
[if IE]
— Строка является функцией, сообщающей версию Internet Explorer, используемую для просмотра документа.[if IE 7]
— Целое число или число с плавающей точкой сообщающее версию браузера. Возвращается логическое значение «true», если номер версии соответствует версии браузера.Функции:
[if WindowsEdition]
— Строка является функцией, сообщающей редакцию Windows используюмую для просмотра документа.[if WindowsEdition 1]
— Строка является функцией, сообщающей редакцию Windows используюмую для просмотра документа.Функции:
[if true]
— Всегда вычисляется как «true».[if false]
— Всегда вычисляется как «false».Операторы:
[if !IE]
— Оператор «не». Размещается непосредственно перед функцией, оператором или subexpression для изменения логического значения экспрешена на обратное.[if lt IE 5.5]
— Оператор «меньше, чем». Возвращает «true», если первый аргумент меньше второго.[if lte IE 6]
— Оператор «меньше, чем или равен». Возвращает «true», если первый аргумент меньше или равен второму.Операторы:
[if gt IE 5]
— Оператор «больше, чем». Возвращает «true», если первый аргумент больше второго.[if gte IE 7]
— Оператор «больше, чем или равен». Возвращает «true», если первый аргумент больше или равен второму.[if !(IE 7)]
— Операторы «subexpression». Используется в сочетании с логическими операторами для создания более сложных expressions.Операторы:
[if (gt IE 5)& (lt IE 7)]
— Оператор «и». Возвращает «true», если все subexpressions вернули «true».[if (IE 6)|(IE 7)]
— Оператор «или». Возвращает «true», если любой из subexpressions возвращает «true».Ресурсы для IE.
<!--[if IE]>HTML<![endif]-->
Ресурсы для альтернативных браузеров.
<!--[if !IE]>HTML<![endif]-->
Ресурсы для IE версии ниже 9.
<!--[if lt IE 9]>HTML<![endif]-->
Ресурсы для IE9 и ниже.
<!--[if lte IE 9]>HTML<![endif]-->
Ресурсы для IE версии выше 8.
<!--[if gt IE 8]>HTML<![endif]-->
Ресурсы для IE8 и выше.
<!--[if gte IE 8]>HTML<![endif]-->
Ресурсы для IE5.5 и выше, но ниже IE7.
<!--[if (gte IE 5.5)&(lt IE 7)]>HTML<![endif]-->
OpenSource компилятор предназначенный для генерации специфического CSS на основе эталонного в контексте результатов идентификации UA.
Разграничение специфического CSS, как для отдельных браузеров, так и для групп браузеров.
Базовая оптимизация производительности путем объединения в один файл всех CSS связанных между собой операторов @import
.
Возможность условного управления импортами стилей из внешних файлов.
В основе принцип Conditional Comments, расширенный на широкий круг браузеров и перенесенный на бэкэнд. Существует несколько реализаций компилятора:
Определяет UA используемого браузера и с помощью двух переменных в GET-запросе передает сведения компилятору:
Динамическая генерация уникальных CSS не подходит для высоконагруженных сайтов.
Возможность приема аргументов командной строки с указанием браузера и его версии (опционально) с целью последующей генерации статических файлов.
Сценарий создания CSS файлов для IE 6, 7 и не-IE браузеров на примере PHP-реализации:
#!/bin/sh
php -q c-css.php -b IE -v 7 source.css > ie7.css
php -q c-css.php -b IE -v 6 source.css > ie6.css
php -q c-css.php source.css > nonie.css
Любой селектор или блок могут быть экранированы префиксом условного оператора четырех основных типов:
Функция browser
адресует CSS определенному браузеру:
Оператор !
- указывает на отрицание утверждения.
Оператор version
- указывает на версию браузера.
Оператор condition
- арифметический оператор:
Функция browser group
- указывает на группу браузеров, согласно уровню поддержки CSS:
Группы браузеров распределены по поколениям на основе практики поддержки браузеров в компании U4EA Technologies.
С полным списком браузеров можно ознакомиться на специальной странице.
Условие может распространяться на весь селектор:
[if IE] .box {
width: 500px;
padding: 100px 0;
}
Также и на его отдельные части:
.some-block {
display: inline-block;
[if lte Gecko 1.8] display: -moz-inline-stack;
[if lte Konq 3.1] float: left;
height: 30px;
[if IE 5.0] margin-top: -1px;
text-decoration: none;
outline: none;
[if IE] text-decoration: expression(hideFocus='true');
Подключение в основной CSS внешний файл стилей, предназначенный для Mobile Safari и файл, предназначенный для всех остальных браузеров:
[if SafMob] @import(''iphone.css'');
[if ! SafMob] @import(''non-iphone.css'');
OpenSource Javascript-библиотека, предназначенная для обнаружения нативной реализации в браузере веб-стандартов.
HTML5, CSS3, Geolocation API, SVG, SMIL, Touch events... Всего 44 позиции.
Расширяемость за счет подключаемых плагинов.
Результат определения — создание логического объекта Javascript и предопределенного класса для элемента <html>
.
Modernizr ≠ polyfill
«Polyfill» – это Javascript-прослойка, добавляющая поддержку стандартных API для устаревших браузеров.
Исключение! Modernizr 1.7+ создает объекты в DOM-дереве документа, соответствующие структурным элементам HTML5 для возможности последующей работы с ними браузеров IE6-8 (html5shiv).
Детальная настройка библиотеки путем выбора подключаемых модулей, отвечающих за определение того или функционала браузера, наличие которого необходимо документу.
Подключение в блоке <head>...</head>
для безопасного использование с другими библиотеками и после <link type="text/css" href="style.css" />
для предупреждения «вспышки» интерфейса после применения стилей, привязанных к динамическим классам.
Определение поддержки необходимого функционала браузером вместо определения User Agent’а через вычисление значения navigator.userAgent
является более надежным способом определения возможностей frontend’а приложения, т.к. UA легко может быть изменен.
Cоздание элемента с назначением ему конкретных инструкций. Браузеры, которые сумеют их интерпретировать, вернут что-то осмысленное, все прочие вернут undefined
или вообще ничего.
Грамотная работа в тандеме со сторонними библиотеками, обеспечивающими поддержку того или иного функционала, нативная реализация которого отсутствует в браузере. Как упоминалось выше, такие библиотеки называются «polyfills». Доступно более 170 библиотек в более чем 40-ка категориях.
SVG, Canvas, Web Storage (LocalStorage and SessionStorage), HTML5 Sectioning Elements, Video, Web SQL Database, Web Forms, Accessibility / ARIA, Web Workers, Web Sockets, Geo-Location, Application Cache, Browser State Management, EventSource, Animated PNG (APNG), Ruby, HTML5 Details and Summary, HTML5 Output, Progress, Menu, Command, Keygen elements, Dataset property, File API / Drag and Drop, Base64 (window.atob and window.btoa), Device Access, WebGL, MathML, (Web) Audio (Data) API, classList, Cross-Document/Domain Messaging (postMessage), Cross-Origin Resource Sharing (CORS), DOM, DOM Range and Selection, DOM Parsing and Serialization, ECMAScript 5, CSS3 Selectors, CSS3 Transforms, CSS3 Styles, CSS3 Media Queries, Microdata API, XBL, Link prefetch/prerender, Flash Javascript runtime, Illustrator export to Canvas, Visibility, Hyphenation.
Неграмотное и неуместное применение полифиллов способно существенно снизить производительность документа!
Здравый смысл и прямые руки путь к успеху.
Cтоит не забывать о возможности применения принципа «graceful degradation».
Безопасная разработка без потери работоспособности с выходом очередной версии браузера с нативной реализацией благодаря полной эмуляции работы стандартного API браузера.
«WebSocket Polyfill» создаст глобальный объект window.WebSocket
с теми же свойствами и методами, свойственными нативной реализации подобного функционала.
Modernizr.load — асинхронный условный загрузчик ресурсов (CSS, JS).
Разработан как отдельное приложение yepnope.js специально для работы с Modernizr.
Опциональное подключение ресурсов на основе результатов тестов.
Множество способов оптимизации для получения максимальной производительности для каждого конкретного случая.
Определение наличия поддержки геолокации и последующая загрузка необходимого сценария в зависимости от результатов проверки. Экономия трафика и увеличение производительности.
Modernizr.load({
test: Modernizr.geolocation,
yep : 'geo.js',
nope: 'geo-polyfill.js'
});
Контроль загрузки необходимых ресурсов и с переключением на резервные. HTML5 Boilerplate вариант:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.js"> </script>
<script>window.jQuery || document.write ('<script src="js/libs/jquery-1.6.1.min.js"></script>') </script>
Modernizr.load([
{
load: '//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.js',
complete: function () {
if ( !window.jQuery ) {
Modernizr.load('js/libs/jquery-1.6.1.min.js');
}
}
},
{
load: 'needs-jQuery.js'
}
]);
Сценарий выполняет загрузку ресурсов последовательно, а не параллельно, что сказывается на производительности.
Используйте этот метод только для загрузки резервных ресурсов!
Нет необходимого вам функционала? Нужны собственные префиксы и фильтры? Не проблема, можно написать свой плагин! Можно пойти дальше и изменить шаги процесса загрузки и даже ее логику.
Документация тестов снабжена примерами кода. Круг применения тестов многообразен и ограничен лишь воображением.
Поддержка настольных браузеров:
Поддержка мобильных браузеров:
На подходе поддержка Blackberry 6+.
Функционал для условной обработки стилевых правил в зависимости от возможностей браузеров.
@supports
проверяет поддержку браузером пары свойство:значение.
Существующий механизм для «graceful degradation» выражен в игнорировании неподдерживаемых свойств или значений свойств.
Проверка пар свойство:значение, их сочетаний, разобщений или отрицаний.
Применение CSS в случае наличия поддержки «display: flexbox»:
@supportss ( display: flexbox ) {
body, #navigation, #content { display: flexbox; }
#navigation { background: blue; color: white; }
#article { background: white; color: black; }
}
@supports not ( display: flexbox ) {
body { width: 100%; height: 100%; background: white; color: black; }
#navigation { width: 25%; }
#article { width: 75%; }
}
Применение CSS в случае наличия поддержки «box-shadow», включая проприетарные реализации:
@supports ( box-shadow: 2px 2px 2px black ) or
( -moz-box-shadow: 2px 2px 2px black ) or
( -webkit-box-shadow: 2px 2px 2px black ) or
( -o-box-shadow: 2px 2px 2px black ) {
.outline {
color: white;
box-shadow: 2px 2px 2px black;
-moz-box-shadow: 2px 2px 2px black;
-webkit-box-shadow: 2px 2px 2px black;
-o-box-shadow: 2px 2px 2px black;
}
}
При совместном применении операторов «and», «or» и «not» условные группы должны быть заключены в отдельные скобки.
@supports ((transition-property: color) or
(animation-name: foo)) and
(transform: rotate(10deg)) {
// ...
}
Функция считается поддерживаемой, если она реализует данное значение данного свойства.
Обратная совместимость определяет правила обработки недействительных свойств и значений — отсутствие либо наличие частичной имплементации спецификации приводит к недействительности правила.
Обратная совместимость позволяет разработчикам использовать резервные упрощенные правила в рамках возможностей браузера, управляя весом правил посредством порядка в каскаде либо с помощью оператора @supports
.
Павел Ловцевич, LOVATA Group