Selectors Level 4 (W3C Working Draft, 21 November 2018) の 4. Logical Combinations に載っている新しい疑似クラス :is()
/ :has()
/ :where()
について調べてみました。
:is()
以前の仕様では :matches()
や :any()
という名称でしたが、最新のドラフトでは :is()
に変更されています。新しい疑似クラスといってもこの仕様自体は2011年ごろから草案に上がっていたようですね。なげー…。
(※ 試しに Gecko のソースコードをちょっと覗いてみたらちゃんとリネームしてましたね。→ https://github.com/mozilla/gecko-dev/commit/fbf94105b88ce3e809467b98958878327e6deac0 )
特長
-
:is()
のカッコ内に複数のセレクターを指定し、それらのどれかにマッチする要素に対し、スタイルを当てる。 -
:is()
の詳細度は、カッコ内に入るセレクターのうち、詳細度が最も高いものと同じになる。
サンプルコード
:is(header, main, footer) > .wrapper {
padding: 20px;
}
/* 詳細度: 1, 0, 1 */
:is(.foo, #bar, ol) > a {
margin-bottom: 20px;
}
/* 詳細度: 0, 2, 0 */
:is(.foo, [bar], ol) > .link {
margin-bottom: 30px;
}
ソース
https://www.w3.org/TR/selectors-4/#matches
https://developer.mozilla.org/en-US/docs/Web/CSS/:is
:has()
これは面白いっすね!2018年2月の草案で初めて出てきた擬似クラスのようです。残念ながらまだどのブラウザも実装していないようなので、実際に試すことはできません。
特長
-
:has()
のカッコ内にあるセレクタにマッチする子要素を持つ親要素の方にスタイルを当てる- ※ ポイントは親要素の方にスタイルを当てるというところ!
サンプルコード
/* 子要素に見出しを持つ section 要素にスタイルを当てる */
section:has(h1, h2, h3, h4, h5) {
border: 3px solid #ddd;
}
/* 直接の子要素に highlight クラスを持つものがある p 要素にスタイルを当てる */
p:has(> .highlight) {
line-height: 1.4;
}
たとえば他にも、 active クラスを持っている li 要素を持つ ul 要素の背景を強調したいなど、いろいろと使いたくなる場面も出てくるのではないでしょうか。
ソース
https://www.w3.org/TR/selectors-4/#relational
https://developer.mozilla.org/en-US/docs/Web/CSS/:has
:where()
:where()
は :is()
と同じ機能を持っていますが、常に詳細度は持たないという点で異なっています。ドキュメントいわく、詳細度を低く保っておき、スタイルを上書きしやすくしたいときなどに便利だそうです。
特長
-
:where()
のカッコ内に複数のセレクターを指定し、それらのどれかにマッチする要素に対し、スタイルを当てる。 -
:where()
の詳細度は常に0。何も持たない。
サンプルコード
/* hover していない a 要素にスタイルを当てる */
a:where(:not(:hover)) {
text-decoration: none;
}
section a {
text-decoration: underline;
}
上記のサンプルにおいて、もし a:not(:hover)
と書いた場合、詳細度は 0:1:1 です(擬似クラスはクラスセレクター/属性セレクターと同じ詳細度)。そのため、 section a
の詳細度 0:0:2 に勝ってしまい、スタイルが当たりません。 :where()
によってこういった事故を防ぐことができます。
ソース
https://www.w3.org/TR/selectors-4/#zero-matches
https://developer.mozilla.org/en-US/docs/Web/CSS/:where