CSSの新しいセレクタが便利!複数のセレクタを1つにまとめられる:is()、さらに詳細度を0にする:where()の使い方
Post on:2021年4月7日
CSSの新しいセレクタが、主要なすべてのブラウザにサポートされました(ただし、IEは除く)。複数のセレクタを1つにまとめられる:is()、同機能でさらにセレクタの詳細度を0にする:where()をどのように使い分ければよいのか紹介します。
:where() has a cool specificity trick, too.
by Chris Coyier
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
最近、:is()疑似セレクタがよく話題になっている
最近、:is()疑似セレクタがよく話題になっています。おそらく、Safari 14に搭載されたためで、主要なすべてのブラウザにサポートされるようになったからでしょう。
:is()を使用すると、セレクタの繰り返しを減らせます。
1 2 3 4 5 6 7 8 9 10 |
/* BEFORE */ .embed .save-button:hover, .attachment .save-button:hover { opacity: 1; } /* AFTER */ :is(.embed, .attachment) .save-button:hover { opacity: 1; } |
Miriamがそれについてツイートし、KevinがYouTubeに動画をアップし、Šimeが記事を公開し、Robinも言及しています。さらに、Bramusの記事では以下の3点を重要なポイントとして強調しています。
- :is()で複数のセレクタを1つにまとめられるのが便利であること
- :is()の詳細度はセレクタの引数で決まること
- :is()は疑似要素セレクタでは動作しないこと(現時点では)
そして、もちろん主な機能としては、冗長で複雑でエラーを起こしやすいセレクタを簡単に記述できることが挙げられます。詳細度の問題は非常に興味深いものです。Miriamは、実際には何も選択せずに詳細度を高めるなど、いくつかのテクニックを指摘しています。
:is()と:where()については、以前の記事もご覧ください。
複数のセレクタを1つにまとめられる:is()
:is()を使用した実際の例を見てましょう。
.buttonのクラスを使用して選択したいとしますが、かなりの詳細度を与えます。
1 2 3 |
:is(.button, #increase#specificity) { /* 詳細度は、(0, 0, 1, 0)ではなく(0, 1, 0, 0)になります。 */ } |
私は昔、下記のような愚かなことをしたことがあります。
1 2 3 4 |
.button.button.button { /* (0, 0, 1, 0)ではなく(0, 0, 3, 0)に強制的に変更します。 */ /* 実際には要素に3つの.buttonクラスがある必要はありません笑 */ } |
:is()を使用したテクニックの方が、私にとっては理解しやすいです。
同じ機能で、詳細度を0にする:where()
逆に、詳細度を下げたい場合はどうすればよいでしょうか?
:where()疑似セレクタの出番です。機能的には:is()とまったく同じですが、セレクタチェーンの一部として選択するものをカンマ区切りのリストで指定します。ただし、:where()の部分の詳細度は0になります。
:where()も主要なすべてのブラウザにサポートされました。
Kevinは動画で、:is()を使った興味深い落とし穴を披露していました。
1 2 3 4 5 6 7 |
.card :is(.title, p) { color: red; } .card p { color: yellow; } |
color: yellow;が勝つと思うかもしれませんが、上の:is()セレクタに.titleが存在することで詳細度は(0, 0, 2, 0)になり、下の(0, 0, 1, 1)に勝ちます。
その代わりに、:where()疑似セレクタを使用するとどうなるでしょう。
1 2 3 4 5 6 7 |
.card :where(.title, p) { color: red; } .card p { color: yellow; } |
:is()を:where()に変更すると、color: yellow;が勝ちます。上の詳細度は(0, 0, 1, 0)になり、下の(0, 0, 1, 1)に負けます。
:is()と:where()のどちらを使用すればよいか
:is()と:where()のどちらを使用すればいいのでしょうか?
時代を超越した確かなアドバイスがあるとは思えないので、どちらがよいとは言えません。少なくとも、わたし達には両方の選択肢があり、困った時に使えるツールがあるということです。
これまでの経験から言えることは、詳細度を低くすることは一般的に健全なことだと思います。詳細度が高いと選択肢が少なくなりますが、詳細度が低いと上書きする余地があります。しかし、:where()の0詳細度はかなり極端で、混乱を招く可能性もあると思います。私の直感では、より高い詳細度を持つセレクタを混ぜる必要がない限り、:is()から始めたいと思います。必要になった時に:where()を使います。
sponsors