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

article a,
aside a,
footer a {
  color: red;
}

Три строки ради одного правила. Если таких правил много — CSS превращается в простыню. :is() и :where() решают это элегантно.

Попробуйте сами

Нажмите на блоки, чтобы увидеть, как один селектор охватывает несколько контекстов:

// нажмите кнопку выше

Как работает :is()

:is() принимает список селекторов и применяет правило к любому из них:

/* было */
article a,
aside a,
footer a {
  color: red;
}

/* стало */
:is(article, aside, footer) a {
  color: red;
}

Результат одинаковый, но второй вариант короче и его проще читать и менять. Если нужно добавить ещё один контейнер, дописываем его в список, а не копируем строку.

Как работает :where()

:where() работает точно так же, но с одним важным отличием — его специфичность всегда равна нулю. Это делает его идеальным для базовых стилей, которые легко переопределить:

/* эти стили легко перебить любым другим правилом */
:where(h1, h2, h3) {
  line-height: 1.2;
  margin-bottom: 0.5em;
}

С :is() специфичность берётся от самого конкретного селектора в списке. С :where() — всегда ноль.

В чём разница — специфичность

Это ключевое различие между ними:

/* :is() берёт специфичность от #header — она высокая */
:is(#header, .nav) a { color: red; }

/* :where() — всегда 0, легко переопределить */
:where(#header, .nav) a { color: red; }

Правило: используйте :is() в обычной работе для сокращения кода, :where() — для сброса стилей и базовых настроек, которые должны легко перебиваться.

Вложенность и комбинации

Оба псевдокласса хорошо работают в сложных селекторах:

/* заголовки h2 и h3 внутри статьи или документа */
:is(article, .document) :is(h2, h3) {
  font-size: 1.4rem;
}

Без них это было бы четыре отдельных строки.

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

Оба псевдокласса поддерживаются в Chrome 88+, Firefox 78+, Safari 14+. Актуально на caniuse.com.

Что запомнить

:is() и :where() сокращают длинные списки селекторов. Разница одна: :is() учитывает специфичность, :where() — нет. Используйте :where() для базовых стилей, :is() — для всего остального.

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