モダン CSS セレクターの威力::has、:is、そして :where
長年、CSS 開発者は「親セレクター」を夢見てきました。つまり、子要素に基づいて要素のスタイルを指定する方法です。また、スタイルシートを肥大化させる長く、繰り返しの多いセレクターリストにも苦労してきました。
モダン CSS はついにこれらの夢を叶えました。:has()、:is()、そして :where() の登場により、セレクターの書き方は根本的に変わりました。
1. :has():ゲームチェンジャーとなる「親セレクター」
:has() 疑似クラスは、間違いなくここ 10 年で最も強力な CSS の追加機能です。特定の要素が含まれているか、または特定の兄弟要素が後に続いているかに基づいて、その要素を選択できます。
「親」としてのユースケース
/* 画像が含まれている場合のみ、カードのスタイルを指定 */
.card:has(img) {
display: flex;
flex-direction: column;
}
/* 「おすすめ」タグがある場合のみ、カードのスタイルを指定 */
.card:has(.featured-badge) {
border: 2px solid gold;
}
「条件」としてのユースケース
入力要素の状態に基づいて、ラベルのスタイルを指定することもできます。
/* 内部のチェックボックスがチェックされている場合、ラベルのスタイルを指定 */
.form-group:has(input:checked) label {
color: green;
font-weight: bold;
}
2. :is():複雑なセレクターの簡素化
このようなコードを書いたことはありませんか?
header h1, header h2, header h3, footer h1, footer h2, footer h3 {
color: blue;
}
:is() 疑似クラスを使用すると、セレクターをグループ化して繰り返しを減らすことができます。
:is(header, footer) :is(h1, h2, h3) {
color: blue;
}
重要な機能:寛容性
従来のセレクターリストとは異なり、:is() は寛容 (forgiving) です。リスト内の 1 つのセレクターが無効であっても、ブラウザはそれを無視し、有効なセレクターにはスタイルを適用し続けます。
3. :where():詳細度ゼロの力
:where() セレクターは :is() と全く同じように機能しますが、1 つ決定的な違いがあります。それは、詳細度(優先順位)が常にゼロであることです。
なぜ詳細度が重要なのか
CSS では、最も詳細度の高いセレクターが優先されます。これにより、スタイルを上書きするために !important や長いセレクターチェーンを使用する「詳細度戦争」がしばしば発生します。
/* これは詳細度に影響を与えません */
:where(.content) p {
color: gray;
}
/* 単純なクラスセレクターで簡単に上書きできます */
.special-p {
color: red; /* :where() は重みを加えないため、こちらが優先されます */
}
:where() は、ユーザーが簡単にスタイルを上書きできるようにしたい CSS リセットやライブラリの作者にとって最適です。
4. 進化した :nth-child と of S
:nth-child(even) はご存知かと思いますが、of キーワードを使って選択をフィルタリングできるようになったことをご存知でしょうか?
/* .visible クラスを持つ要素の中で、2 番目の項目を選択 */
li:nth-child(2 of .visible) {
background: yellow;
}
これは、いくつかの項目が display: none で非表示になっているような動的なリストにおいて非常に便利です。
5. 詳細度計算機:数学的な仕組みを理解する
CSS の詳細度は、次の 3 つの列を使って計算されます:(A, B, C)
- A:ID セレクター
- B:クラスセレクター、属性セレクター、疑似クラス
- C:要素セレクター、疑似要素
新しいセレクターの影響:
:is()と:has():その詳細度は、引数リスト内の最も詳細度が高いセレクターと等しくなります。:where():常に詳細度は (0, 0, 0) です。
FAQ:よくある質問
Q: :has() はすべてのブラウザでサポートされていますか?
A: はい!2023 年後半時点で、:has() は Chrome、Safari、Firefox、Edge の最新バージョンでサポートされています。モダンなウェブプロジェクトで安心して使用できます。
Q: :is() と :where() はどちらを使うべきですか?
A: グループ化したセレクターに通常通りの詳細度を持たせたい場合は :is() を使用してください。ベーススタイルやリセットのように、スタイルを非常に上書きしやすくしたい場合は :where() を使用してください。
Q: :has() はパフォーマンスに影響しますか?
A: ブラウザは :has() を大幅に最適化しています。1 ページに何百回も使用するとわずかな影響があるかもしれませんが、ほとんどの UI パターンにおいては、非常に高速かつ効率的です。
よりクリーンで宣言的な CSS を書こう
これらのセレクターをマスターすることで、HTML 内の「ユーティリティクラス」の数を大幅に減らし、ロジックを本来あるべき場所、つまり CSS スタイルシートに保つことができます。
あなたのセレクターの重さを確認してみませんか?当サイトの CSS セレクター詳細度計算機(近日公開予定)で、CSS の数学をマスターしましょう。