複数要素の 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()は、従来書いていた長くて重複の多いコードを、短く重複なく書けるようにしてくれます。使いこなし、安全で快適な開発をしましょう。