:where()

:where()CSS擬似クラス関数で、セレクターリストを引数として取り、列挙されたセレクターのうちの何れかに当てはまるすべての要素を選択します。

/* ヘッダー、メイン、フッターの何れかの中にある段落に
   カーソルをかざしたときに選択 */
: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()詳細度が常に 0 であるのに対して、 :is() は引数内で最も詳細度の高いセレクターの詳細度を取ります。

寛容なセレクター解釈

仕様では、:is():where()寛容なセレクターリストを受け入れると定義されています。

CSS では、セレクターリストを使用する場合、いずれかのセレクターが無効であれば、リスト全体が無効であると判断されます。 is():where() を使用する場合、 1 つでも解釈に失敗するとセレクターリスト全体が無効とみなされるのではなく、不正確または対応していないセレクターは無視され、他のものが使用されます。

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

Will still parse correctly and match :valid even in browsers which don't support :unsupported, whereas:

:valid, :unsupported {
  ...
}

Will be ignored in browsers which don't support :unsupported even if they support :valid.

:where() と :is() の比較

この例では :where() がどのように作用するのかを示し、 :where():is() の違いも説明しています。

以下のような HTML を想定してください。

<article>
  <h2>:is() でスタイル付けしたリンク</h2>
  <section class="is-styling">
    <p>こちらがメインコンテンツです。これは<a href="https://mozilla.org">リンクを含んでいます</a></section>

  <aside class="is-styling">
    <p>こちらが脇コンテンツです。これも<a href="https://developer.mozilla.org">リンクを含んでいます</a></aside>

  <footer class="is-styling">
    <p>こちらがフッターです。これも<a href="https://github.com/mdn">リンク</a>を含んでいます。
  </footer>
</article>

<article>
  <h2>:where() でスタイル付けしたリンク</h2>
  <section class="where-styling">
    <p>こちらがメインコンテンツです。これは<a href="https://mozilla.org">リンクを含んでいます</a>.
  </section>

  <aside class="where-styling">
    <p>こちらが脇コンテンツです。これは<a href="https://developer.mozilla.org">also リンクを含んでいます</a>.
  </aside>

  <footer class="where-styling">
    <p>こちらがフッターです。これも<a href="https://github.com/mdn">リンク</a>を含んでいます。
  </footer>
</article>

このやや矛盾した例では、2 つの記事があり、それぞれがセクション、脇、フッターを含んでいます。これらの記事は、子要素をマークするために使われるクラスによって異なります。

中のリンクの選択をより簡単にして、しかし区別できるようにするために、次のように :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 a {
  color: blue;
}

これは赤いリンクに作用しません。 :is() の中のセレクターは全体のセレクターの詳細度で算出され、クラスセレクターは要素セレクターよりも高い詳細度を持っているからです。

しかし、 :where() 内のセレクターは詳細度が 0 なので、オレンジ色のフッターリンクは単純セレクターによって上書きされてしまいます。

Note: この例は 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
Selectors Level 4
# zero-matches

ブラウザーの互換性

BCD tables only load in the browser

関連情報