複数要素の a:hover
と a:focus
にスタイルをあてたいとき、次のようなコードを書いていませんか?
.section1 a:hover,
.section1 a:focus,
.section2 a:hover,
.section2 a:focus {
color: lightpink;
}
:is()
という擬似クラス関数を使えば、短く、重複のないコードが書けます。
:is(.section1, .section2) a:is(:hover, :focus) {
color: lightpink;
}
また、:is()
と同時期に、:where()
や :not()
の複数要素指定といった便利な機能も使えるようになりました。
本記事では、各機能の基礎から使い方までを、実例を交えて紹介します。
:is()
とは何か?:where()
とは何か?:not()
とは何か?
:is()
の基本的な使い方
:is()
とは、複数のセレクタを1つにまとめるための擬似クラス関数です。引数(()
内のこと)に指定したセレクタに対して、スタイルを設定します。
:is(セレクタ1, セレクタ2, セレクタ3) {
/* スタイル */
color: red;
}
簡単な例を見てみましょう。 .box1
, .box2
, .box3
の3つの要素に対してボーダーを引くには次のようにします。
:is(.box1, .box2, .box3) {
border: 1px solid lightblue;
}
.box1
, .box2
, .box3
の、「すべての要素の中の」p
要素の色を変えるには、次のようにします。
:is(.box1, .box2, .box3) p {
color: lightpink;
}
これは次のコードと同じ意味です。
.box1 p,
.box2 p,
.box3 p {
color: lightpink;
}
:is()
の挙動のポイント
:is()
を使うとまるで1つのセレクタのような挙動になります。
たとえば、.box
という1つのセレクタ内のp
要素の色を変えるには、次のようにしますね。
.box p {
color: lightpink;
}
.box
という1つのセレクタ部分を、まるまる:is()
で置き換えると次のコードになります。.box1
要素と.box2
要素内にある、p
要素の色を変えるという指定になります。
:is(.box1, .box2) p {
color: lightpink;
}
つまり、:is()
を使うと、これまで1つしかセレクタを指定できなかった箇所に、複数のセレクタを指定できるようになるのです。
もうひとつ例を見てみましょう。
.container
要素の中のひとつの.child
要素のフォントサイズを変えるには、次のようにしますね。
.container .child {
font-size: 40px;
}
.child
という1つのセレクタ部分を、まるまる:is()
で置き換えると次のコードになります。.container
要素内にある.child1
と.child2
の2つのフォントサイズを変えるという指定になります。
.container :is(.child1, .child2) {
font-size: 40px;
}
このように、「:is()
はまるで1つのセレクタのように振る舞う」ということを覚えておくと、挙動の理解がしやすくなります。
:is()
は何個でも使える
:is()
は何個でも使えるので、次のようなスタイル指定ができます。
:is(.section1, .section2) a:is(:hover, :focus) {
color: lightpink;
}
分解すると、次のようになります。
:is(.section1, .section2)
.section1
と.section2
をまとめている
:is(.section1, .section2)
.section1
と.section2
をまとめている
これは、次のCSS指定と同じ意味です。
.section1 a:hover,
.section1 a:focus,
.section2 a:hover,
.section2 a:focus {
color: lightpink;
}
後者のように1つ書いてもいいですが、.section1
やa:hover
など、同じ記述を何度もする必要があります。人間ですので、コードは書けば書くほどミスするのです。重複なくシンプルに書いておいたほうが、ミスも減るでしょう。
デモ
デモはこちらから確認できます。セクション1, セクション2にホバーフォーカスしたときだけ、フォント色がピンク色になることを確認できます。
:not()
でも複数のセレクタが指定できるようになった
:is()
は、引数(()内
)のセレクタに合致する要素すべてを選択するものでした。逆に、どのセレクタにも合致しないときに使えるのが:not()
です。
:not()
自体は従来から使えましたが、最近のブラウザの進化により、:not()
では複数のセレクタを指定できるようになりました。
次のHTMLコードを見てください。3つのp
タグがあります。
<p class="a">A</p>
<p class="b">B</p>
<p>C</p>
このうち、.a
でも.b
でもないp
要素だけ色を変えたいとき、どうすればよいでしょうか?
従来は、次のようにするしかありませんでした。
p:not(.a):not(.b) {
color: lightpink;
}
最近のブラウザでは、次のような書き方ができます。
p:not(.a, .b) {
color: lightpink;
}
筆者的には、この機能がとても便利です。.foo
や.bar
ではない要素に対してスタイルを設定するというケースは多かったものの、昔は:not()
に複数のセレクタを指定できずに不便に感じていました。現在のやり方のほうが直感的でラクです。
詳細度が常に0
の:where()
:is()
と似た疑似クラスで、:where()
があります。:is()
は()
内の詳細度になるのに対し、:where()
の詳細度はつねに0
です。
次の:is()
の例では、div a
はred
になります。
:is(div.foo a) {
color: red;
}
div a {
color: blue;
}
次の:where()
の例では、div a
はblue
になります。
:where(div.foo a) {
color: red;
}
div a {
color: blue;
}
たとえば、リセットCSSをつくる際、詳細度を上げたくない場合などに活用できます。
対応ブラウザ
:is()
、:where()
、セレクタリスト対応の:not()
は、2021年初頭より全ブラウザで対応済みです。
まとめ
今回紹介した:is()
や:not()
は、従来書いていた長くて重複の多いコードを、短く重複なく書けるようにしてくれます。使いこなし、安全で快適な開発をしましょう。
TechFeedにて、CSSの:is()ついての解説記事を書きました💐
.container a:is(:hover, :focus) { color: blue; }
という書き方ができ、全ブラウザ対応済み。
「まるで1つのセレクタのように振る舞う」と覚えると、挙動が理解しやすいです🐰
普通に便利そう!