Знакомство с правилом CSS @supports

Знакомство с правилом CSS @supports

От автора: в этой статье я подробно рассмотрю правило @supports и связанное с ним JavaScript API.

 

Для решения проблемы поддержки новейших технологий в браузерах используются два основных метода: метод грациозной деградации и прогрессивного улучшения. Метод грациозной деградации позволяет пользователям, использующим современные браузеры, ощутить весь функционал передовых технологий. А тем, кто использует старые версии браузера, будет предоставлена версия сайта с ограниченным функционалом.

С техникой прогрессивного улучшения разработчики устанавливают базовую линию для дизайна, тот уровень пользовательского опыта, который поддерживает большинство браузеров. В таких веб-приложениях есть встроенная функция определения браузера. Данную функцию они могут использовать для увеличения функционала сайта по мере возможностей браузера, а значит, и для улучшения пользовательского опыта. Самый распространенный инструмент в технике прогрессивного улучшения это JS библиотека Modernizr.

Modernizr программно проверяет, поддерживает ли браузер веб-технологии следующего поколения, и соответственно возвращает true или false. Вооружившись этим знанием, вы можете использовать новые свойства в поддерживающих их браузерах, а для старых браузеров использовать надежные, проверенные методы.

Звучит хорошо, но вот уже некоторое время на слуху метод куда лучше. Функцию определения можно реализовать при помощи CSS запросов через правило @supports.

Функция определения браузера через @supports

Правило @supports является частью CSS3 спецификации по условным правилам, которая также включает в себя более широкое правило @media, которым все мы пользуемся при создании адаптивного дизайна. Медиа запросы позволяют обнаружить такие свойства как ширина и высота области окна браузера, в то время как @supports позволяет проверить поддержку браузером пары CSS свойство/значение.

Рассмотрим простой пример. Скажем, на веб-странице есть изображение, к которому вы хотите применить режимы наложения. Режимы наложения не поддерживаются в старых браузерах. Однако вместо того, чтобы показывать пользователям, чей браузер не поддерживает данную функцию, изображение по умолчанию, можно, если не полностью копировать эффект, то хотя бы показывать что-то похожее. Ниже показано, как проверить поддержку режимов наложения через @supports:

@supports (mix-blend-mode: overlay) {

  .example {
    mix-blend-mode: overlay;
  }

}

Чтобы добавить стили в браузеры без поддержки mix-blend-mode, необходимо использовать синтаксис:

@supports not(mix-blend-mode: overlay) {

  .example {
    /* альтернативные стили */
  }

}

Несколько замечаний:

Условие должно быть внутри скобок. Т.е. запись @supports mix-blend-mode: overlay { … } неверна. Тем не менее, если добавить лишние пары скобок, все будет работать нормально. К примеру, запись @supports ((mix-blend-mode: overlay)) верна.

В условии должно быть как само свойство, так и его значение. В примере выше мы проверяем свойство mix-blend-mode на значение overlay.

Добавление в конце конструкции !important не влияет на правильность кода.

Давайте сделаем по примеру выше небольшое демо. Браузеры с поддержкой mix-blend-mode будут применять стили из блока @supports() { … }; остальные браузеры будут брать стили из блока @supports not() { … }.

<article class="artwork">
  <img src="myimg.jpg" alt="cityscape">
</article>
@supports (mix-blend-mode: overlay) {

  .artwork img {
    mix-blend-mode: overlay;
  }

}

@supports not(mix-blend-mode: overlay) {

  .artwork img {
    opacity: 0.5;
  }

}

Демо на CodePen:

Тест нескольких условий зараз

В тестах свойств через @supports нам не ограничивают количество условий, которые можно составить в одной конструкции. Поставить несколько условий можно при помощи логических операторов and, or, и вышеупомянутого not. Оператор конъюнкции and проверяет соблюдение нескольких условий:

@supports (property1: value1) and (property2: value2) {
  element {
    property1: value1;
    property2: value2;
  }
}

С помощью оператора дизъюнкции or набор стилей можно задать различным свойствам. Очень удобно, если некоторым свойствам или значениям нужно прописать вендорные префиксы:

@supports (property1: value1) or (-webkit-property1: value1) {
  element {
    -webkit-property1: value1;
    property1: value1;
  }
}

В одном @supports правиле можно комбинировать операторы and и or:

@supports ((property1: value1) or 
          (-webkit-property1: value1)) and 
          (property2: value2) {
  element {
    -webkit-property1: value1;
    property1: value1;
    property2: value2;
  }
}

Ключевое значение при группировке условий играют скобки. Просто расставить операторы and, or или not не получится. Также способ группировки условий в скобках определит порядок, в котором будут читаться данные условия. В коде выше дизъюнкция or читается первой, затем результат условия сравнивается со следующим условием and.

При помощи слова not можно проверить одно условие зараз. К примеру, код ниже неверен:

@supports not (property1: value1) and (property2: value2) {
  /* стили... */
}

Вместо этого необходимо сгруппировать все условия под одно ключевое слово not при помощи скобок. Ниже правильная запись кода:

@supports not ((property1: value1) and (property2: value2)) {
  /* стили... */
}

Осталось убедиться, что после not стоит пробел, а также с обеих сторон от and и or.

Операторы в действии

Если браузер поддерживает градиенты и режимы наложения, то к нему можно применить набор стилей, как показано ниже (я разбил код ниже на несколько строк для лучшей читаемости):

@supports (mix-blend-mode: overlay) and 
  (background: linear-gradient(rgb(12, 185, 242), rgb(6, 49, 64))) {

  .artwork {
    background: linear-gradient(rgb(12, 185, 242), rgb(6, 49, 64));
  }

  .artwork img {
    mix-blend-mode: overlay;
  }

}

Так как некоторым старым Android браузерам необходим префикс -webkit- для линейных градиентов, давайте встроим дополнительное условие в блок @supports:

@supports (mix-blend-mode: luminosity) and 
  (
    (background: linear-gradient(rgb(12, 185, 242), rgb(6, 49, 64))) or 
    (background: -webkit-linear-gradient(rgb(12, 185, 242), rgb(6, 49, 64)))
  ) 

{

  .artwork {
    background: -webkit-linear-gradient(rgb(12, 185, 242), rgb(6, 49, 64));
    background: linear-gradient(rgb(12, 185, 242), rgb(6, 49, 64));
  }

  .artwork img {
    mix-blend-mode: luminosity;
  }

}

К примеру, на вашем сайте стоят значения режимов наложения luminosity и saturation, которые на момент написания статьи не поддерживаются в браузере Safari. Но вы хотите добавить альтернативные стили для этих браузеров. В таком случае нам поможет @supports not и and:

@supports not (
    (mix-blend-mode: luminosity) and 
    (mix-blend-mode: saturation)
  ) 
{

  .artwork img {
    mix-blend-mode: overlay;
  }

}

Все демо можно найти на CodePen:

JavaScript и CSS запросы

Воспользоваться всеми преимуществами CSS запросов можно при помощи JavaScript CSS интерфейса и функции supports(). Функцию Css.supports() можно написать двумя способами. Первый и наиболее поддерживаемый синтаксис принимает два аргумента: свойство и его значение, а возвращает true или false:

CSS.supports('mix-blend-mode', 'overlay')

Не забудьте написать свойство и его значение в кавычках. Спецификация ясно говорит, что функция возвращает true, если выполняются два условия:

Имя переданного свойства «буквально совпадает с именем CSS свойства», которое должен поддерживать браузер;

Значение будет «проверено, если это значение поддерживается свойством».

Под буквальным совпадением спецификация понимает, что символы перехода на новую строку не обрабатываются и пробелы не удаляются. Поэтому не ставьте лишних пробелов в конце или начале слова, иначе вернется false. Альтернативный синтаксис принимает только один аргумент в скобках:

CSS.supports('(mix-blend-mode: overlay)')

Данный синтаксис удобнее для проверки нескольких условий при помощи and и or. Ниже маленький пример. Скажем, вы хотите проверить, поддерживает ли браузер режим наложения luminosity. Если да, то JS динамически добавит класс luminosity-blend к соответствующему элементу. В противном случае будет добавлен класс noluminosity. Соответственно к элементу применятся нужные стили.

.luminosity-blend {
  mix-blend-mode: luminosity;
}

.noluminosity {
  mix-blend-mode: overlay;
}

Если использовать первый синтаксис, то JS код будет следующий:

var init = function() {
  var test = CSS.supports('mix-blend-mode', 'luminosity'),
  targetElement = document.querySelector('img');

  if (test) {
    targetElement.classList.add('luminosity-blend');
  } else {
    targetElement.classList.add('noluminosity');
  }

};

window.addEventListener('DOMContentLoaded', init, false);

Если вам нравится новый синтаксис с одной переменной, просто замените соответствующую строку кода на строку ниже:

var test = CSS.supports('(mix-blend-mode: luminosity)')

Поддержка в браузерах

Все современные браузеры кроме IE11 и Opera Mini поддерживают правило @supports. Готово ли правило @supports к выходу в свет? Самый лучший ответ я нашел у Tiffany Brown:

«… с осторожностью подходите к задаче применения критически важных стилей через @supports… Определите базовые стили – стили, которые поддерживаются всеми браузерами. Затем, используйте @supports для того, чтобы переписать или дополнить те стили, которые можно записать в браузерах с помощью новых свойств. CSS Master, p.303»

Заключение

В данной статье я исследовала нативный CSS метод определения поддержки свойств через правило @supports. Также было рассмотрено соответствующее JS API, с помощью которого можно проверить текущую поддержку браузером последних CSS свойств при помощи гибкого метода Css.supports().

Поддержка CSS запросов довольно хорошая, однако не повсеместная. Но все же, если вы хотите использовать @supports в своих проектах, вам может помочь стратегическое размещение стилей в CSS файле, как было сказано Tiffany Brown, а также css-supports.js polyfill от Han Lin Yap.

Если вы посмотрели демо к статье и у вас появились вопросы, или у вас уже был опыт использования @supports, пишите об этом в комментариях.

Автор: Maria Antonietta Perna

Источник: http://www.sitepoint.com/

Редакция: Команда webformyself.

Курс по CSS3

Прямо сейчас изучите CSS3 с нуля!

Смотреть курс

Метки:

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree