Как работает @supports в CSS

Как работает @supports в CSS

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

Эта функция называется @ supports CSS, и это выглядит так:

Для чего? Ну, это немного сложно. Лично я считаю, что все это обычно не нужно. В CSS есть естественные механизмы отката: если браузер не понимает комбинацию свойство: значение, он будет игнорировать ее и благодаря каскаду использовать что-то объявленное перед ним, если что-то есть. Иногда это может использоваться, чтобы иметь дело с запасными вариантами, и конечный результат был немного менее расширенным. Я, конечно, не из тех парней, у которых все должно быть одинаковым в каждом браузере, но я и не из тех, кто пишет сложные резервные варианты. Я обычно предпочитаю ситуацию, когда отказ комбинации свойство: значение не влияет радикальным образом на функционал.

Тем не менее, у @supports, безусловно, есть варианты использования! И, как я выяснил, готовя этот пост, многие люди используют его для множества интересных вещей.

Классический вариант использования

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

Хорошая сетка! Повторение и автоматическое заполнение столбцов — приятная особенность CSS-сетки. Но, конечно, есть браузеры, которые не поддерживают Grid или поддерживают не все его функции, которые я использую выше.

Например, iOS добавила поддержку CSS-сетки в версии 10.2, но iOS имеет поддержку flexbox с версии 7. Это существенный разрыв для того, чтобы было много людей с более старыми устройствами iOS, которые поддерживают flexbox, но не grid. Я уверен, что есть и другие примеры пробелов, но вы, вероятно, поняли идею.

Может быть допустимо не оставлять запасной вариант для этого, в зависимости от требований. Например, вертикально расположенные элементы уровня блока, а не многостолбцовый макет сетки. Это часто подходит для меня. Но допустим, что это не подходит, например, для фотогалереи или чего-то, что должно иметь какую-то базовую решетчатую структуру. В этом случае лучше подойдет, если мы начнем с flexbox по умолчанию и используем @supports для применения сеточных функций там, где они поддерживаются…

«Откат» — это код вне блока @supports (свойства над блоком в приведенном выше примере), а код grid размещается либо внутри, либо ниже. Блок @supports не изменяет специфичность, поэтому нам нужен порядок источников, чтобы обеспечить, чтобы переопределение работало.

Обратите внимание, что мне пришлось сбросить поля для div внутри блока @supports. Это та вещь, которую я нахожу немного раздражающей. Между этими двумя сценариями достаточно много пересечений, поэтому требуется супер-понимание того, как они влияют друг на друга. Разве это не заставляет вас желать, чтобы это можно было полностью разделить логически…

В блоках @supports есть логика «not», но это не значит, что она должна использоваться всегда. Джен Симмонс привела этот пример в статье под названием «Использование запросов функций в CSS» несколько лет назад:

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

Очень привлекательно писать код в таких логически разделенных блоках @supports, потому что тогда он каждый раз начинается с нуля и не нуждается в переопределении предыдущих значений и работе с этими логическими трудностями. Но давайте вернемся к той же ситуации с iOS, которую мы рассматривали ранее … @supports введен в iOS версии 9 (прямо между вводом flexbox в iOS 7 и сетки в iOS 10.2). Это означает, что любой резервный код flexbox в блоке @supports, использующем оператор not для проверки поддержки (display: grid) {}, не будет работать ни в iOS 7, ни в 8, что означает, что для резервного варианта теперь также требуется резервный вариант. Уф!

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

Мы, вероятно, дойдем до того момента, когда сможем беспрепятственно использовать подобные взаимоисключающие блоки. Говоря о которых…

@supports, вероятно, будет более полезным со временем.

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

По сути, IE 11 и любое iOS-устройство на iOS 8 являются болевыми точками. Если ваши требования не включают их, тогда вы можете использовать @supports более свободно.

Ирония заключается в том, что для очень немногих CSS-функций приводятся понятные варианты использования @supports, но несколько все же есть! По-видимому, можно попробовать новые модные вещи, такие как Houdini.

Когда @supports не делает ничего полезного

Я видел много случаев использования @supports, где конечный результат такой же, как и без него. Например…

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

Существуют браузерные расширения для экспериментов с @supports. Их два!

Feature Queries Manager Ире Адеринокун

CSS Feature Toggle Extension Кита Кларка

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

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

Инструмент Ире, о котором она писала в статье «Создание расширения DevTools Manager для запросов функций», использует несколько иной подход: он показывает запросы функций, которые вы фактически написали в своем CSS, и предоставляет переключатели для их включения и выключения. Я не думаю, что он работает через iframes, поэтому я открыл режим отладки, чтобы использовать его в CodePen.

Другие реальные примеры использования для @supports

Вот один пример от Эрика Ворхеса. Здесь он устанавливает некоторые пользовательские чек-боксы и переключатели, но все это упаковывает в блок @supports. Ни один из стилей не будет применен, если блок не пройдет проверку поддержки.

Вот еще несколько примеров, с которыми я столкнулся:

Джо Райт и Тьяго Нуньес упомянули, что используют его для position: sticky;. Я хотел бы увидеть демо! Как и в случае, когда вы используете position: sticky;, но должны сделать что-то еще, кроме того, чтобы просто оставить неработающим этот элемент в не поддерживающех браузерах.

Кит Грант и Матиас Отт упоминают, что используют его для object-fit: contain;. У Матиаса есть демонстрационная программа, в которой используется трюк позиционирования для создания изображения, заполняющего контейнер, который затем упрощается и улучшается с помощью этого свойства, когда оно доступно.

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

Рик Щенник упоминает свойство backdrop-filter. Он говорит: «Когда оно поддерживается, непрозрачность цвета фона часто нуждается в тонкой настройке».

Нура Сауд упомянул, что @supports может быть использован для распознавания Edge через определенный вендорный префикс свойства: @supports (-ms-ime-align:auto) { }.

Эмбер Вайнберг упомянула об использовании его для clip-path, чтобы регулировать размер или отступы для элемента, когда clip-path недоступно.

Ральф Хольцманн упомянул об использовании для проверки на предмет «notch» (переменных среды).

Стейси Квернмо упомянула, что она использовала @supports для различных свойств, необходимых для сброса заглавных символов. Джен Симмонс упоминает этот вариант использования в своей статье. В CSS есть свойство initial-letter, которое фантастически работает для заглавных букв, но используется в сочетании с другими свойствами, которые вы можете вообще не захотеть применять, если не поддерживаются initial-letter (или если есть совершенно другой сценарий отката).

Вот бонусный пример от Ника Колли, в котором не используется @supports, а вместо этого используется @media! По сути то же самое. Это может предотвратить «зависание» состояния наведения на сенсорных устройствах, например:

Логика в @supports

Основная:

not:

and:

or:

комбинации:

Вариант JavaScript

В JavaScript есть API для этого. Чтобы проверить, существует ли…

Чтобы использовать это, передайте свойство в одном параметре, а значение в другом:

… или передайте все в одной строке, отражающей синтаксис CSS:

Проверка селекторов

На момент написания этой статьи только Firefox поддерживает такое тестирование (с экспериментальным флагом), но есть способ протестировать поддержку селекторов с помощью @supports. Демо MDN:

Как насчет вас?

Конечно, мы хотели бы увидеть в комментариях множество вариантов использования @supports. Так что поделись с нами!

Автор: Chris Coyier

Источник: //css-tricks.com/

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

Метки:

Похожие статьи:

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