Перевод статьи от Matthias Ott «Detecting CSS Selector Support with JavaScript».

🚀 Вам бесплатно доступен тренажёр по HTML и CSS.

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

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

Если браузер поддерживает свойство display:grid, он будет использовать стили из этой директивы, а иначе просто проигнорирует весь блок кода.

Если хотите проверить целый селектор, используйте функцию @supports selector(), которую удивительно хорошо поддерживают браузеры.

@supports selector(:nth-child(1 of .class)) {
  /* Сделать что-то */
}

Если хотите узнать больше, Крис Койер написал неплохую заметку о @supports selector().

В текущем проекте я оказался в ситуации, где нужно было проверить поддержку относительно нового селектора : where (). Ситуация непростая: и :where(), и @supports selector() появились в браузерах примерно в одно и то же время, так что если вы хотите таким способом проверить, поддерживается ли селектор старыми браузерами вроде Safari 13, то ничего не получится. А мне нужно было нормальное решение для старых браузеров, так что я стал искать альтернативы и в итоге решил использовать JavaScript.

Я нашёл это решение в посте Леа Веру. В 2011 она писала о том, как проверить поддержку CSS-селекторов через создание нового элемента style с нужным селектором. После этого мы проверяем, появилось ли правило в таблице стилей. Это хороший ход даже для браузеров старше IE8.

Но Леа упомянула и более простой способ: использование document.querySelector() в выражении с try... catch (). И учитывая, что Selectors API уже работает довольно хорошо, я остановился на этом варианте. Смотрите сами:

try {
  document.querySelector(selector)
} catch (error) {
  console.error(error)
}

Браузер попробует выполнить метод document.querySelector() с тем селектором, который мы хотим проверить. Если селектор не поддерживается, программа выдаст исключение и выполнит код в блоке catch. В примере выше ошибка выведется в консоль.

Обернем это в переиспользуемую функцию, которая вернет true, если селектор поддерживается, или false, если нет.

const isSelectorSupported = (selector) => {
  try {
    document.querySelector(selector)
    return true
  } catch (error) {
    return false
  }
}

Теперь вы можете проверить поддержку любого селектора и, например, добавить класс прямо к элементу <html>, если браузер в порядке.

if (isSelectorSupported(":where(body)")) {
  document.documentElement.classList.add("supports-where")
}

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