Визначення CSS можливостей: Modernizr або директива @support?

13

Від автора: у даній навчальній статті я розгляну два підходи, що дозволяють визначити, чи підтримуються браузером певні CSS можливості чи ні. У першому підході використовується інструмент Modernizr, популярна JavaScript бібліотека, а в другому – директива @support, що подає надії CSS рішення.

Визначення можливостей з допомогою Modernizr

Як вже було сказано, Modernizr – це легка JavaScript бібліотека, яка підтримку HTML5 і CSS3 можливостей у вашому браузері. Поки відбувається завантаження сторінки, Modernizr працює у фоновому режимі і виконує тести на визначення можливостей. Потім він зберігає результати у вигляді властивостей JavaScript об’єкта та у вигляді класів у елемента html. Про це трохи пізніше.

Щоб встановити і використовувати Modernizr, ви можете відвідати офіційний сайт і завантажити потрібну версію.

Визначення CSS можливостей: Modernizr або директива @support?

Примітка: на момент написання статті поточною версією Modernizr є версія 2.8.3, хоча версія 3 майже готова. За фактом, команда, яка розробляє бібліотеку, планує запустити нову версію вже через кілька тижнів. З коротким оглядом нової версії можна ознайомитися тут. Більш того, ви можете завантажити бета-версію по даному посиланню.

Після скачування помістіть JavaScript файл з бібліотекою в папку з вашим проектом і підключіть його в області вашій html сторінки. І останній, але не менш важливий момент полягає в тому, щоб додати клас no-js елементу html, щоб активувати функціонал Modernizr.

В наступних двох розділах даної статті я розгляну основи роботи з Modernizr. Для більш глибоко вивчення даного інструменту прочитайте документацію.

Визначення через CSS

Як вже говорилося раніше, Modernizr додає деяку кількість класів до елемента html. Імена класів залежать від браузерної підтримки. Якщо браузер не проходить деякі з тестів, то Modernizr додає префікс no — перед вбудованими іменами класів. Наприклад, припустимо, що ми тестуємо ефекти відбиття. Тоді елемент html в браузері Chrome 40 буде виглядати наступним чином:

Визначення CSS можливостей: Modernizr або директива @support?

У той час як в браузері Firefox 35 наступне:

Визначення CSS можливостей: Modernizr або директива @support?

Зверніть також увагу на клас js. Якщо при запуску Modernizr в браузері включити JavaScript, то Modernizr замінює старий клас no-js на новий. Грунтуючись на результатах тестів Modernizr, ми можемо змінювати наші таблиці стилів.

Приклади

Для початку представимо базовий HTML код, який буде використовуватися на всьому протязі даної навчальної статті:

CSS Reflections

Використовуючи класи, які нам надав Modernizr, ми змінюємо наші стилі для елемента h2 наступним чином:

h2 {
color: #c0ccdb;
font-size: 3em;
}
.cssreflections h2 {
-webkit-box-reflect: below -.45em -webkit-gradient(linear, left, top, left bottom, from(transparent), color-stop(0%, transparent), to(rgba(255, 255, 255, 0.75)));
}
.no-cssreflections h2 {
text-shadow: 0 1px 0 #136ed1,
0 2px 0 #126ac9,
0 3px 0 #1160b6,
0 4px 0 #105cad,
0 5px 0 #0f56a2,
0 6px 1px rgba(0,0,0,.1),
0 0 5px rgba(0,0,0,.1),
0 1px 3px rgba(0,0,0,.3),
0 3px 5px rgba(0,0,0,.2),
0 10px 5px rgba(0,0,0,.25),
0 10px 10px rgba(0,0,0,.2),
0 20px 20px rgba(0,0,0,.15);
}

Браузери на «движку» Webkit, що підтримують ефекти відбиття, відобразять елемент h2 наступним чином:

Визначення CSS можливостей: Modernizr або директива @support?

У той час як інші (хоча б ті, які підтримують властивість text-shadow) застосують інший ефект, заснований на ефекті 3D тексту Марка Отто (Mark Otto):

Визначення CSS можливостей: Modernizr або директива @support?

Визначення через JavaScript

Другий спосіб отримання результатів тестів Modernizr полягає в JavaScript. Як вже було сказано, Modernizr створює об’єкт з іменами властивостей тих можливостей, підтримку яких він буде перевіряти. В більшості випадків в якості повертаються значення буде або true, або false.

На наступному скріншоті видно, як Firefox 35 відображає об’єкт Modernizr (вкладка Консоль):

Визначення CSS можливостей: Modernizr або директива @support?

Як ми бачимо властивість Modernzir.cssreflections має значення false. Це відбувається тому, що Chrome, Safari і Opera – це єдині браузери, які підтримують ефекти відбиття (це дійсно так на момент написання статті). Ось як ми можемо відтворити попередній приклад з допомогою JavaScript, додаючи вручну класи reflection і no-reflection до нашого елементу

:

var element = document.getElementById(‘reflection’);
if (Modernizr.cssreflections) {
element.className = ‘reflection’;
} else {
element.className = ‘no-reflection’;
}

Потім прописуємо відповідне оформлення в CSS:

.reflection {
/* застосовуємо властивість reflection */
}
.no-reflection {
/* застосовуємо властивість text-shadow */
}

Визначення можливостей з допомогою директиви @support

Безсумнівно, Modernizr є цінним інструментом в арсеналі будь-якого фронтенд розробника. Але хіба не було б краще мати можливість відтворювати тести Modernizr на чистому CSS? На щастя, у нас є така можливість завдяки директиві @support. Суть полягає у використанні умовних правил, які дозволяють нам застосовувати різні стилі в залежності від браузерної підтримки. Це працює також як і медіа-запити. І так, крім версії CSS, дана можливість є і в JavaScript.

Готові поглянути на це ближче?

Визначення через CSS

Для визначення можливостей у вашому CSS вам потрібно використовувати правила @supports і @supports not. Синтаксис виглядає ось так:

@supports(test condition) {
/* застосовуємо правила */
}
@supports not(test condition) {
/* застосовуємо правила */
}

В умові містяться пари властивість: значення тих можливостей, які ви хочете протестувати. Браузери, які підтримують певні можливості, будуть застосовувати задані стильові правила, які ми вкажемо в правилі @supports. В іншому випадку будуть застосовуватися стилі з правила @supports not.

За допомогою логічних операторів AND і/або OR ми можемо створити складні тести. Проте, слід пам’ятати, що дані оператори повинні відділятися круглими дужками.

Давайте розглянемо два приклади. Як ми вже знаємо, наш HTML код дуже простий! Це просто елемент h2. У першому прикладі ми використовуємо властивість background-color, щоб визначити який колір фону елемента body. Щоб було трохи цікавіше, ми також створимо CSS змінну. Браузерну підтримку можна розбити на наступні категорії:

Браузери, які підтримують директиву @support і CSS змінні (в даний час тільки Firefox 31+).

Браузери, які підтримують директиву @support, але не підтримують CSS змінні.

Браузери, які не підтримують ні директиву @support, ні CSS змінні.

Залежно від обставин елемент body буде мати різний колір тла. В результаті у нас вийде наступний CSS код:

body {
—bg-color: #98FB98;
background-color: khaki;
}
@supports (background-color: var(—bg-color)) {
body {
background-color: var(—bg-color);
}
}
@supports not(background-color: var(—bg-color)) {
body {
background-color: tomato;
}
}

Наприклад, в Safari, який відноситься до третьої категорії браузерів, наш елемент буде виглядати ось так:

Визначення CSS можливостей: Modernizr або директива @support?

Потім в Chrome, який підтримує тільки директиву @support і отже належить до другої категорії, наш елемент виглядає ось так:

Визначення CSS можливостей: Modernizr або директива @support?

І нарешті в Firefox, який належить до першої категорії, наш елемент виглядає ось так:

Визначення CSS можливостей: Modernizr або директива @support?

Інший приклад

В даному випадку ми розширимо наше тестове умова і допишемо друге правило. Якщо бути точніше, то зараз ми вже відбираємо браузери, які підтримують не тільки ефекти відбиття, але ще й ефект обведення тексту. Ось відповідний код:

@supports ((/* умова для ефектів відбиття */) and (-webkit-text-stroke: 1px tomato)) {
h2 {
/* застосовуємо властивість reflection */
-webkit-text-stroke: 1px tomato;
}
}
@supports not ((/* умова для ефектів відбиття */) and (/* умова для ефектів обведення тексту */))
{
h2 {
/* застосовуємо властивість text-shadow */
}
}

Наприклад, браузери (на момент написання статті до таких відноситься тільки Chrome 28+), які підтримують директиву @support, ефекти відображення і ефекти обведення тексту, відобразять елемент h2 наступним чином:

Визначення CSS можливостей: Modernizr або директива @support?

Визначення через JavaScript

Механізм роботи директиви @support для визначення можливостей можна реалізувати і через JavaScript. Для цього необхідно використовувати метод CSS.supports. Ось можливі параметри даного методу:

CSS.supports(propertyName, propertyValue)
CSS.supports(test condition)

Даний метод повертає значення типу Boolean , яке вказує, чи підтримує браузер потрібні можливості чи ні. Нарешті, нам потрібно обернути параметри в одинарні або подвійні лапки. Використовуючи JavaScript версію, останній приклад можна представити наступним чином:

var result = CSS.supports(‘(/* умова для ефектів відбиття */) and (/* умова для ефектів обведення тексту */)’);
var element = document.getElementById(‘reflection’);
if(result) {
element.className = ‘reflection’;
} else {
element.className = ‘no-reflection’;
}

Браузерна підтримка

В цілому, браузери добре підтримують директиву @support. На момент написання статті Firefox (22+), Chrome (28+) і Opera (12.1+) повністю підтримують даний CSS функціонал. Хочеться сподіватися, що в наступних версіях браузера IE також навчиться розуміти умовні правила (розробники браузера працюють над цим!).

Визначення CSS можливостей: Modernizr або директива @support?

Полифиллы

Якщо ви хочете використовувати директиву @support в ваших проектах, але вас не влаштовує поточна браузерна підтримка, ви можете скористатися наступними корисними полифиллами:

css-supports.js

CSS.supports

fq-polyfill

Висновок

В даній навчальній статті я розповів про двох методах, які забезпечують надійну кросбраузерність обробку можливостей. Скориставшись одним з цих методів, ви зрозумієте всю вигоду проектування сайтів та додатків під конкретні можливості, а не браузери. На поточний момент Modernizr є стабільним рішенням, але повсюдне використання директиви @support вже не за горами, тому вибір за вами!