近年、CSSには多くの擬似クラスが追加され、過去とは異なり、ほんの一部のブラウザだけで実装されているわけではありません。今日はいくつかのCSS擬似クラスを紹介し、実際の例を通じてレイアウトをサポートします。
:is
:where
:has
:lang
:focus-within
:first-child
と:last-child
:is
以前、複数のセレクタに同じCSSルールを適用するには、以下のように書いていました。
.a-class,
.b-class {
font-size: 25px;
}
これに問題はありませんが、:is
を使用すると、次のように宣言を簡略化できます。
:is(.a-class, .b-class) {
font-size: 25px;
}
セレクタを適用する必要がある場合、:is
を使用すると読みやすくなります。まだWorking Draftの段階ですが、Can I useのデータによると、98.1%のユーザーが使用できます。
単一のクラスだけでなく、他のセレクタと組み合わせることもできます。
:is(.a-class, .b-class) a:hover {
opacity: 0.8;
}
:where
:where
は:is
と同じ機能を持っていますが、優先順位に違いがあります。:where
を使用すると、優先順位は*
と同じになります。しかし、:is
は異なり、リスト内の最も高い優先順位に基づいて最終的な優先順位が決まります。
Hello
この例では、#page
があるため、クラスセレクタよりも優先順位が高いため、最終的な色は赤になります。:where
を使用する場合、セレクタに追加の優先順位はありません。
Hello
そのため、最終的な色は黄色になります。 上記の結果から、使用シーンは次のように分けられます。
:where()
を使用してグローバルスタイル(リセットなど)を作成し、変更が必要な場合は直接上書きできるようにする。:is()
を使用して複数のセレクタに対してローカルスタイルを適用し、すべてのセレクタに同じ優先順位が適用されることを保証する。
:has
:has
は、条件に一致する子要素が存在する場合に親要素に一致します。説明は少しややこしいですが、例を使うとわかりやすいです。便利なシーンの一つは、「子要素がフォーカスされたときに親要素のスタイルを変更したい」というものです。
検索機能を実装する場合、検索アイコンを入力フィールドの横に配置することがあります。入力フィールドがフォーカスされたとき、単に入力フィールドにフォーカスのスタイルを適用したいだけでなく、アイコンを含む入力フィールド全体にフォーカスのスタイルを適用したい場合があります。この場合、input:focus
では望む効果を得ることができません。
以前の解決策は、CSSセレクタが有効になるようにDOMの構造を変更するか、JavaScriptでフォーカスイベントを監視し、親要素にフォーカスがあることを伝えるためのクラスを追加する方法でした。しかし、:has
を使用することで、構造を変更する必要なくCSS内で直接実現できます。
入力にフォーカス!
これにより、input
がフォーカスされたとき、.form:has(input:focus)
が有効になり、スタイルが親要素に適用されます。"子要素が条件を満たす場合に親要素を一致させる"ということは、フロントエンド開発者の長い間の願いであり、これで大きな前進が実現されました。
:has
には他の使用方法もありますが、特に「子要素が特定の条件に一致する場合にこのセレクタを適用する」シーンで使用します。
たとえば、テーマを切り替える場合、body:has(input[type="checkbox"]:checked)
を使用すると、JavaScriptを使用せずに色のテーマを切り替えることができ、適切なDOM構造を保持できます。
:has
の使用シーンについては、webkitのブログにさらなる使用例があります。:has
は比較的新しい擬似クラスであり、ブラウザのサポート率はまだ高くありません(82.92%)。導入する場合は注意が必要です。
:focus-within
経験豊富なフロントエンド開発者の一部にとって、先ほどの例は実際には:focus-within
で置き換えることができることに気づいたはずです。:focus-within
は、子要素がフォーカスされたときに一致し、このため親要素のスタイルを変更することができます。
たとえば、フォーカス時にフォームにbox-shadow
を追加したい場合は、次のように書くことができます。
ただし、:focus-within
はフォーカスにのみ適用でき、多様な選択肢を作成することはできません。フォーカスされていない場合に一致させる必要がある場合は、より柔軟な:has
を使用することができます。
:lang
多言語ウェブサイトを実装する際、<html>
にlang
属性を追加して現在のウェブサイトの言語を示すことがあります。時には異なる言語ごとに異なるフォントを表示する必要がある場合、:lang
を使用しない場合は、次のように書く必要があります。
html[lang="zh"] p { font-family: var(--font-zh); }
html[lang="en"] p { font-family: var(--font-en); }
これは少し冗長ですが、:lang
を使用すると、セレクタの構文を簡略化できます。
p:lang(en) {
font-family: var(--font-en);
}
p:lang(zh) {
font-family: var(--font-zh);
}
:first-childと:last-child
これらは非常に一般的な擬似クラスですが、多くのフロントエンド開発者が知らないことに気付きました。これらの擬似クラスを使用すると、最初の子要素または最後の子要素を指定できます。最も一般的なシーンは、margin-right
を指定する際に最後の要素に適用したくない場合です。その場合は、次のように書くことができます。
.tab {
margin-right: 8px;
}
.tab:last-child {
margin-right: 0;
}
または、より簡潔にするために:not
と組み合わせることもできます。
.tab:not(:last-child) {
margin-right: 8px;
}
なぜJavaScriptを使用しないのですか?
一部のユーザーはJavaScriptを有効にしない場合があります。特にブログなど、主に静的な記事のあるウェブサイトでは、多くの読者がJavaScriptを有効にしない可能性があります。しかし、読みやすさを損なわずに読書体験を向上させたい場合、上記で紹介した擬似クラスはレイアウトの問題を解決するのに役立ちます。シンプルなものが求められるのであれば、複雑なものを使う必要はありません。