19
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

新しい擬似クラス :is() / :has() / :where() の仕様を調べてみた

Last updated at Posted at 2018-12-14

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() の詳細度は、カッコ内に入るセレクターのうち、詳細度が最も高いものと同じになる。

サンプルコード

sample1.css
:is(header, main, footer) > .wrapper {
  padding: 20px;
}
sample2.css
/* 詳細度: 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() のカッコ内にあるセレクタにマッチする子要素を持つ親要素の方にスタイルを当てる
    • ※ ポイントは親要素の方にスタイルを当てるというところ!

サンプルコード

sample3.css
/* 子要素に見出しを持つ 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。何も持たない。

サンプルコード

sample4.css
/* 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

19
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?