:where()

CSS псевдокласс :where() в качестве аргумента принимает список селекторов и выбирает только те элементы, которые могут быть выбраны из переданного списка.
/* Выбирает любой параграф внутри header, main
   или footer на который наведен курсор мыши */
:where(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

/* Пример приведенный выше эквивалентен следующему */
header p:hover,
main p:hover,
footer p:hover {
  color: red;
  cursor: pointer;
}

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

Парсинг forgiving-селектора

В спецификации псевдоклассы :is() и :where() относятся к так называемому forgiving selector list (прощающий список селекторов).

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

:where(:valid, :unsupported) {
  ...
}

Пример выше будет успешно распарсен и для :valid будут применены CSS-правила, даже если в браузере не поддерживается :unsupported, в то время как:

:valid, :unsupported {
  ...
}

Код будет полностью проигнорирован в браузерах, которые не поддерживают :unsupported, даже не смотря на то, что они поддерживают :valid.

Примеры

Сравнение :where() и :is()

В этом примере показывается как работает :where(), а так же демонстрируется разница между :where() и :is().

Возьмем следующий HTML-код:

<article>
  <h2>:is()-styled links</h2>
  <section class="is-styling">
    <p>Here is my main content. This <a href="https://mozilla.org">contains a link</a>.
  </section>

  <aside class="is-styling">
    <p>Here is my aside content. This <a href="https://developer.mozilla.org">also contains a link</a>.
  </aside>

  <footer class="is-styling">
    <p>This is my footer, also containing <a href="https://github.com/mdn">a link</a>.
  </footer>
</article>

<article>
  <h2>:where()-styled links</h2>
  <section class="where-styling">
    <p>Here is my main content. This <a href="https://mozilla.org">contains a link</a>.
  </section>

  <aside class="where-styling">
    <p>Here is my aside content. This <a href="https://developer.mozilla.org">also contains a link</a>.
  </aside>

  <footer class="where-styling">
    <p>This is my footer, also containing <a href="https://github.com/mdn">a link</a>.
  </footer>
</article>

В примере выше у нас представлено две статьи, каждая из которых содержит следующиее блоки: section, aside и footer. Каждый из блоков имеет свой CSS-класс.

Теперь при помощи псевдоклассов :is() и :where() зададим цвет для ссылок в простой форме, как в примере ниже:

html {
  font-family: sans-serif;
  font-size: 150%;
}

:is(section.is-styling, aside.is-styling, footer.is-styling) a {
  color: red;
}

:where(section.where-styling, aside.where-styling, footer.where-styling) a {
  color: orange;
}

Что если позже мы захотим переопределить цвет ссылок в footer'ах используя простой селектор?

footer a {
  color: blue;
}

Это не будет работать для ссылок красного цвета, потому что специфичность селекторов внутри :is() выше, чем специфичность селектора вышеприведенного кода. Селектор классов имеет бо́льшую специфичность, чем селектор элемента.

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

Примечание: Вы так же можете найти этот пример на Github; смотрите is-where.

Синтаксис

:where( <complex-selector-list> )

где
<complex-selector-list> = <complex-selector>#

где
<complex-selector> = <compound-selector> [ <combinator>? <compound-selector> ]*

где
<compound-selector> = [ <type-selector>? <subclass-selector>* [ <pseudo-element-selector> <pseudo-class-selector>* ]* ]!
<combinator> = '>' | '+' | '~' | [ '||' ]

где
<type-selector> = <wq-name> | <ns-prefix>? '*'
<subclass-selector> = <id-selector> | <class-selector> | <attribute-selector> | <pseudo-class-selector>
<pseudo-element-selector> = ':' <pseudo-class-selector>
<pseudo-class-selector> = ':' <ident-token> | ':' <function-token> <any-value> ')'

где
<wq-name> = <ns-prefix>? <ident-token>
<ns-prefix> = [ <ident-token> | '*' ]? |
<id-selector> = <hash-token>
<class-selector> = '.' <ident-token>
<attribute-selector> = '[' <wq-name> ']' | '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'

где
<attr-matcher> = [ '~' | | | '^' | '$' | '*' ]? '='
<attr-modifier> = i | s

Спецификации

Specification Status Comment
Selectors Level 4
Определение ':where()' в этой спецификации.
Рабочий черновик Initial definition.

Совместимость с браузерами

BCD tables only load in the browser

Смотрите также