Новая CSS директива @supports

http://davidwalsh.name/css-supports
  • Перевод
Проверка на поддержку конкретных технологий браузером с помощью JavaScript по праву считается наилучшей практикой при клиент-сайд разработке (Часто используют другой способ, заключающийся в проверке из какого браузера пользователь просматривает страницу — Прим. пер.), но, к сожалению, такую проверку нельзя было сделать с использованием только лишь CSS. Firefox, Chrome и Opera недавно объявили о поддержке CSS директивы @supports и CSS.supports (JavaScript), которые помогут разработчикам определять справится ли браузер пользователя с CSS свойством или нет. Давайте посмотрим на них в деле!

Проверить свой браузер
(Если надпись зеленая, то ваш браузер поддерживает @supports, если красная, то нет. Также можно посмотреть на сообщение в консоли браузера.)

CSS @supports


Синтаксис директивы @supports такой же, как и у @media запросов:
@supports(prop:value) {
	/* стили */
}

Директива @supports предоставляет разработчикам различные варианты ее использования.

Простая проверка свойства

@supports (display: flex) {
	div { display: flex; }
}

Это наиболее простой способ использования.

Ключевое слово not

@supports в паре со словом not осуществляет проверку на отсутствие поддержки какого-либо свойства:
@supports not (display: flex) {
	div { float: left; } /* задан альтернативный стиль */
}


Множественные проверки и условия

Множественные проверки могут быть осуществлены при помощи цепочки слов or и and:
/* or */
@supports (display: -webkit-flex) or
          (display: -moz-flex) or
          (display: flex) {

    /* добавляем сюда ваших клёвых стилей */
}

/* and */
@supports (display: flex) and (-webkit-appearance: caret) {
	
	/* и сюда тоже добавим  */
}

Если необходимо выполнить несколько множественных проверок, то, как и во многих языках программирования, можно использовать скобки:
/* and and or */
@supports ((display: -webkit-flex) or
          (display: -moz-flex) or
          (display: flex)) and (-webkit-appearance: caret) {

    /* стили сюда */
}

Синтаксис условий @supports совпадает с таковым у @media запросов.

JavaScript CSS.supports


JavaScript аналогом для @supports является метод window.CSS.supports. Есть два варианта его использования. Первый включает передачу двух аргументов — свойства и его значения:
var supportsFlex = CSS.supports("display", "flex");

Второй вариант требует передачи в качестве аргумента целой строки:
var supportsFlexAndAppearance = CSS.supports("(display: flex) and (-webkit-appearance: caret)");

Перед использованием JavaScript аналога важно сперва проверить поддержку этой технологии браузером. Opera использует другое название метода, что слегка увеличивает код:
var supportsCSS = !!((window.CSS && window.CSS.supports) || window.supportsCSS || false);


Использование @supports


В большинстве случаев, лучший способ использовать @supports это установить определенный резервный набор стилей и затем заменить их на другие, в случае если нужное свойство поддерживается. Прекрасный повод для использования @supports — описание расположения элементов. Некоторые новейшие браузеры поддерживают flexbox, в то время как остальные плетутся позади. В таком случае можно написать следующий код:
section {
	float: left;
}

@supports (display: -webkit-flex) or
          (display: -moz-flex) or
          (display: flex) {

    section {
      display: -webkit-flex;
      display: -moz-flex;
    	display: flex;
    	float: none;
    }
}

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

Подключение @supports

Если вы горите желанием попробовать новые технологии вроде @supports, вам следует потратить какое-то время на установку самой последней edge-версии браузера Canary, Firefox Nightly, или Opera Next. Opera 12.1, WebKit Nightly и Firefox Nightly — все они поддерживают @supports. Старые версии Firefox предоставляют соответствующую поддержку после включения правила [layout.CSS.supports-rule.enabled].

@supports является долгожданным дополнением к спецификациям CSS и JavaScript. Определение поддержки конкретных технологий браузером — лучшая практика, и @supports является более удобным и подходящим способом для этого, чем различные хаки. Подозреваю, что в ближайшие пару лет мы увидим всплеск использования директивы @supports, одновременно с увеличением популярности и удобства flexbox.

Полезные ссылки


http://caniuse.com/css-featurequeries
http://dev.w3.org/csswg/css-conditional/#at-supports
Твиттер, посвященный технологии
О flexbox на хабре
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 28
  • +15
    только мы научились какать через котельную соломинку…
    • –2
      Блин. Коктельную соломинку.

      А «котельной соломинки» нет, хоть в интернете она часто упонимается!
  • +1
    IE, как всегда, на вершине прогресса.
    • 0
      Кто знает, может в какой-нибудь ночной сборке тоже есть поддержка. Правда сборки не публичны.
    • +37
      • +1
        шедевр! подняли настроение! 5 баллов!
        • +1
          К сожалению, это не фотошоп. Если у вас нету AdBlock, то именно такая картинка висит на Хабре справа от топика.
      • +12
        @supports (@supports) {… }
        • +2
          @supports (@supports) { @supports not (display:inline-block) { .inline { float:left } } @supports (display:inline-block) { .inline { display:inline-block } } }
          Только вложения в вложениях вложений, только хардкор.
          • +1
            Действительно: мне кажется что именно с этой директивы и надо было разработку CSS3 начинать, а сейчас уже как-то… поздновато
          • +2
            Было уже: habrahabr.ru/post/154123/
            • +1
              В той статье не описан JavaScript метод и приведены устаревшие данные касательно поддержки браузерами.
            • 0
              Поддержка @supports и CSS.supports() реализована и в Blink: codereview.chromium.org/13646013
              • 0
                Где это можно применять на практике? Пока что не вижу сильной пользы от этой директивы, если честно.
                • +1
                  Вы смеётесь что ли? Появляются новые свойства, которые позволяют делать что-то, что раньше решалось ворохом костылей. Если упомянутое свойство поддерживается, костыли можно выключить.
                  • +1
                    Но проблема то в том, что у меня сейчас даже хром (ещё не обновился/не вышел апдейт) не поддерживает это свойство, что уж говорить про чуть более древние браузеры.
                    • +1
                      Умрут древние браузеры. Вы ведь не используете тег LAYER и не проверяете, что браузер DIV поддерживает? А для меня лет 15 назад это было будничным занятием.
                      • 0
                        Я вижу два варианта:

                        1. Мы поддерживаем браузер, который не поддерживает свойство Х.
                        Тогда нам всё-равно придётся реализовывать при помощи старых свойств.
                        Тогда зачем реализовывать при помощи новых? Чтобы поддерживать две вёрстки?

                        2. Мы не поддерживаем старый браузер.
                        Тогда просто вставляем новую вёрстку и старые браузеры рушатся.
                        • 0
                          В варианте номер один вы забываете, что эмуляция свойств, которых нет в старых браузерах, часто делается допобвязкой и костылями, которая может тормоза давать при сложной вёрстке.

                          Кроме того, вы не рассмотрели вариант №3:
                          если свойство поддерживается, делаем эффект на нём, если нет, делаем что-нибудь, на что хотя бы не противно смотреть.
                          • 0
                            С @supports будет удобнее верстать в соответствии с подходом progressive enhancement, от меньшего к большему.
                            Например, на странице нужно разместить контент в шести блоках.
                            Если браузер не поддерживает 3D transforms, то, к примеру, задаем каждому ширину 300px, float:left и изменение цвета фона при наведении мышки на блок.
                            Если же браузер поддерживает 3D transforms, то можно разместить блоки совершенно иным образом, задать иную ширину и при наведении делать transform: rotateY(130deg); вместо изменения цвета фона.

                            Да, придется поддерживать 2 разных набора стилей для элемента. Если бы стояла цель добиться определнной эффектности на каком-то сайте с помощью использования новейших css фич, то я бы поддерживал.
                    • 0
                      Поддерживает браузер скруглённые углы — рисуем углы. Поддерживает флекс — используем… Тот же modernizr, вид в профиль.
                      • 0
                        Тот же Modernizr, только без JS и позволяющий проверить даже самые тонкие аспекты поддержки.
                        • 0
                          Поддерживает браузер скруглённые углы — рисуем углы

                          А разве мы и так не можем нарисовать скруглённые углы? Ну например чем отличаются следующих два кода?

                          .target {
                            border-radius: 5px;
                          }
                          
                          @supports (border-radius) {
                            .target {
                              border-radius: 5px;
                            }
                          }
                          
                          • 0
                            Ничем. Вы рассматриваете не тот случай, для которого @supports нужен.
                        • 0
                          Реально можно применять на практике, чтобы «включить» Flexbox последней спецификации
                        • +1
                          CSS.supports polyfill IE6+ и всё остальные браузеры.

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.