新しくサポートされた最新のCSS疑似クラスセレクターのガイド
公開: 2022-03-10 疑似クラスセレクターは、コロン文字「 :
」で始まり、現在の要素の状態に基づいて一致するセレクターです。 状態は、ドキュメントツリーに相対的である場合もあれば、 :hover
や:checked
などの状態の変化に応答する場合もあります。
:any-link
セレクターレベル4で定義されていますが、この疑似クラスはかなり長い間クロスブラウザーをサポートしてきました。 any-link
疑似クラスは、 href
がある限り、アンカーハイパーリンクと一致します。 :link
と:visited
の両方を同時に一致させるのと同じ方法で一致します。 基本的に、訪問したステータスに関係なくすべてのリンクに適用するcolor
などの基本的なプロパティを追加する場合、これにより1つのセレクターによってスタイルが減少する可能性があります。
:any-link { color: blue; text-underline-offset: 0.05em; }
特異性に関する重要な注意点は、aがクラスの特異性を持っているため、カスケードの下位に配置されa
いる場合でも、 :any-link
がセレクターとしてのa
に勝つことです。 次の例では、リンクは紫色になります。
:any-link { color: purple; } a { color: red; }
したがって、 :any-link
を導入する場合、それらが特異性を直接競合する場合はa
セレクターとしてのインスタンスにそれを含める必要があることに注意してください。
:focus-visible
Web全体で最も一般的なアクセシビリティ違反の1つは、リンク、ボタン、 :focus
状態のフォーム入力などのインタラクティブ要素のoutline
を削除することだと思います。 このoutline
の主な目的の1つは、主にキーボードを使用してナビゲートするユーザーの視覚的なインジケーターとして機能することです。 目に見えるフォーカス状態は、これらのユーザーがインターフェイス上でタブを移動し、インタラクティブな要素とは何かを強化するのに役立つ経路探索ツールとして重要です。 具体的には、目に見える焦点はWCAG成功基準2.4.11:焦点の外観(最小)でカバーされています。
:focus-visible
疑似クラスは、ユーザーエージェントがヒューリスティックを介してフォーカスリングを表示する必要があると判断した場合にのみフォーカスリングを表示することを目的としています。 別の言い方をすれば、ブラウザは、入力メソッド、要素のタイプ、インタラクションのコンテキストなどに基づいて、 :focus-visible
をいつ適用するかを決定します。 キーボードとマウスの入力を備えたデスクトップコンピューターを介したテストの目的で、インタラクティブな要素にタブで移動すると:focus-visible
スタイルが添付されますが、クリックするとは表示されません。ただし、テキスト入力とtextareasは:focus-visible
を表示する必要があります。すべてのフォーカス入力タイプで:focus-visible
されます。
注:詳細については、 :focus-visible
仕様の作業ドラフトを確認してください。
FirefoxおよびChromiumブラウザーの最新バージョンは、 :focus-visible
一致する場合にUAが:focus
スタイルを削除する必要があるという仕様に従って、フォーム入力で:focus-visible
を処理しているようです。 Safariはまだ:focus-visible
をサポートしていないため、アクセシビリティのためにoutline
が削除されないように、フォールバックとして:focus
スタイルが含まれていることを確認する必要があります。
次の一連のスタイルを使用したボタンとテキスト入力が与えられたら、何が起こるか見てみましょう。
input:focus, button:focus { outline: 2px solid blue; outline-offset: 0.25em; } input:focus-visible { outline: 2px solid transparent; border-color: blue; } button:focus:not(:focus-visible) { outline: none; } button:focus-visible { outline: 2px solid transparent; box-shadow: 0 0 0 2px #fff, 0 0 0 4px blue; }
ChromiumとFirefox
-
input
:focus-visible
を優先して要素がマウス入力でフォーカスされている場合は、:focus
スタイルを正しく削除して、border-color
を変更し、キーボード入力でoutline
を非表示にします。 -
button
::focus
のアウトラインを削除するbutton:focus:not(:focus-visible)
の追加ルールなしで:focus-visible
を使用するだけでなく、キーボード入力でのみbox-shadow
を表示できるようにします
サファリ
input
:focus
スタイルのみを引き続き使用しますbutton
これは、クリック時に:focus
スタイル:focus-visible
の意図を部分的に尊重しているように見えますが、キーボード操作では:focus
スタイルを表示しています。
したがって、今のところ、 :focus
スタイルを含め続けてから、デモコードで許可されている:focus-visible
を使用するように段階的に拡張することをお勧めします。 テストを続行するためのCodePenは次のとおりです。
:focus-within
:focus-within
疑似クラスは、最新のすべてのブラウザーでサポートされており、ほとんど親セレクターのように機能しますが、非常に特定の条件に対してのみ機能します。 包含要素にアタッチされ、子要素が:focus
に一致する場合、スタイルを包含要素やコンテナ内の他の要素に追加できます。
この動作を使用するための実用的な拡張機能は、関連する入力にフォーカスがある場合のフォームラベルのスタイル設定です。 これを機能させるには、ラベルをラップしてコンテナに入力し、そのコンテナに:focus-within
をアタッチして、ラベルを選択します。
.form-group:focus-within label { color: blue; }
これにより、入力にフォーカスがあるときにラベルが青色に変わります。
このCodePenデモには、 .form-group
コンテナに直接アウトラインを追加することも含まれています。
:is()
「任意のマッチ」疑似クラスとも呼ばれる:is()
は、セレクターのリストを取得して、マッチングを試みることができます。 たとえば、見出しのスタイルを個別に一覧表示する代わりに、 :is(h1, h2, h3)
のセレクターの下でそれらをグループ化できます。
:is()
セレクターリストに関するいくつかの固有の動作:
- リストされたセレクターが無効な場合、ルールは引き続き有効なセレクターと一致します。
:is(-ua-invalid, article, p)
与えられると、ルールはarticle
とp
に一致します。 - 計算された特異性は、最も高い特異性を持つ渡されたセレクターの特異性と等しくなります。 たとえば、
:is(#id, p)
は#id
— 1.0.0 —の特異性を持ちますが、:is(p, a)
は0.0.1の特異性を持ちます。
無効なセレクターを無視する最初の動作は、重要な利点です。 1つのセレクターが無効なグループで他のセレクターを使用すると、ブラウザーはルール全体を破棄します。 これは、ベンダープレフィックスが依然として必要ないくつかのインスタンスで機能し、プレフィックス付きセレクターとプレフィックスなしセレクターをグループ化すると、すべてのブラウザーでルールが失敗します。 :is()
を使用すると、これらのスタイルを安全にグループ化でき、一致する場合は適用され、一致しない場合は無視されます。
私にとって、前述のように見出しスタイルをグループ化することは、このセレクターですでに大きな勝利です。 これは、次のような重要ではないスタイルを適用するときに、フォールバックなしで快適に使用できるタイプのルールでもあります。
:is(h1, h2, h3) { line-height: 1.2; } :is(h2, h3):not(:first-child) { margin-top: 2em; }
この例(私のプロジェクトSmolCSSのドキュメントスタイルに由来)では、ベーススタイルから継承されたline-height
が大きいか、 margin-top
がないことは、サポートされていないブラウザーにとって実際には問題ではありません。 それは単に理想的とは言えません。 まだ:is()
を使用したくないのは、インターフェイスを大幅に制御するグリッドやフレックスなどの重要なレイアウトスタイルです。
さらに、別のセレクターにチェーンされている場合、ベースセレクターが:is()
内の子孫セレクターと一致するかどうかをテストできます。 たとえば、次のルールは、記事の直接の子孫である段落のみを選択します。 ユニバーサルセレクターは、 p
ベースセレクターへの参照として使用されています。
p:is(article > *)
現在の最高のサポートのために、それを使い始めたい場合は、 :-webkit-any()
と:matches()
を使用して重複するルールを含めることにより、スタイルを2倍にすることもできます。 これらの個別のルールを作成することを忘れないでください。そうしないと、サポートしているブラウザでさえそれを破棄します。 つまり、次のすべてを含めます。
:matches(h1, h2, h3) { } :-webkit-any(h1, h2, h3) { } :is(h1, h2, h3) { }
この時点で言及する価値があるのは、新しいセレクター自体とともに、 @supports selector
である@supports
の更新されたバリエーションがあることです。 これは、 @supports not selector
としても利用できます。
注:現在(最新のブラウザーの)、Safariのみがこのルールをサポートしていません。
次のような方法で:is()
のサポートを確認できますが、Safariは:is()
をサポートしていますが、 @supports selector
をサポートしていないため、実際にはSafariのサポートを失うことになります。
@supports selector(:is(h1)) { :is(h1, h2, h3) { line-height: 1.1; } }
:where()
疑似クラス:where()
は、1つの重要な違いを除いて、 :is()
)とほぼ同じです。つまり、常にゼロ特異性を持ちます。 これは、フレームワーク、テーマ、および設計システムを構築している人々にとって信じられないほどの意味を持っています。 :where()
を使用すると、作成者はデフォルトを設定でき、ダウンストリームの開発者は、特異性が衝突することなくオーバーライドまたは拡張機能を含めることができます。
次の一連のimg
スタイルについて考えてみます。 :where()
を使用すると、より高い特異度セレクターを使用しても、特異度はゼロのままになります。 次の例では、画像の境界線はどの色になると思いますか?
:where(article img:not(:first-child)) { border: 5px solid red; } :where(article) img { border: 5px solid green; } img { border: 5px solid orange; }
最初のルールは、完全に:where()
内に含まれているため、特異性はゼロです。 したがって、2番目のルールに直接反して、2番目のルールが勝ちます。 最後のルールとしてimg
要素のみのセレクターを導入すると、カスケードのために勝ちます。 これは、 :where()
部分では特異性が向上しないため、 :where(article) img
ルールと同じ特異性で計算されるためです。
フォールバックと一緒:where()
を使用することは、ゼロ特異性機能のために少し難しくなります。これは、その機能が:is()
で使用する理由である可能性が高いためです。 また、フォールバックルールを追加すると、その性質上、 :where()
に勝る可能性があります。 また、 @supports selector
よりも全体的なサポートが優れているため、これを使用してフォールバックを作成しようとしても、(あるとしても)多くの利益が得られる可能性は低くなります。 基本的に、 :where()
のフォールバックを正しく作成できないことに注意し、独自のデータを注意深くチェックして、独自のオーディエンスに使用を開始しても安全かどうかを判断してください。
上からimg
セレクターを使用する次のCodePenを使用して:where()
をさらにテストできます。
拡張:not()
基本の:not()
セレクターはInternet Explorer 9以降でサポートされています。ただし、セレクターレベル4は、 :is()
や:where()
)と同様に、セレクターリストを取得できるようにすることで:not()
を拡張します。
次のルールは、ブラウザのサポートで同じ結果を提供します。
article :not(h2):not(h3):not(h4) { margin-bottom: 1.5em; } article :not(h2, h3, h4) { margin-bottom: 1.5em; }
セレクターリストを受け入れる:not()
の機能は、最新のブラウザーをサポートしています。
:is()
で見たように、拡張:not()
には、 *
を使用して子孫としてベースセレクターへの参照を含めることもできます。 このCodePenは、 nav
の子孫ではないリンクを選択することでこの機能を示しています。
ボーナス:前のデモには、 h2
またはh3
要素のいずれかの隣接する兄弟ではない画像を選択するために:not()
と:is()
をチェーンする例も含まれています。
提案されているが「危険にさらされている」— :has()
非常にエキサイティングな提案ですが、実験的な方法でさえそれを実装している現在のブラウザがない最後の疑似クラスは:has()
です。 実際、セレクターレベル4の編集者ドラフトには「リスクあり」と記載されています。これは、実装を完了するのが困難であると認識されているため、推奨から除外される可能性があることを意味します。
実装された場合、 :has()
は本質的に、多くのCSSの人々が利用できることを切望していた「親セレクター」になります。 :focus-within
と:is()
の両方を子孫セレクターと組み合わせた場合と同様のロジックで機能します。子孫の存在を探しますが、適用されるスタイルは親要素になります。
次のルールが与えられた場合、ナビゲーションにボタンが含まれていると、ナビゲーションの上下のパディングが減少します。
nav { padding: 0.75rem 0.25rem; nav:has(button) { padding-top: 0.25rem; padding-bottom: 0.25rem; }
繰り返しになりますが、これは現在、実験的にもどのブラウザにも実装されていませんが、考えるのは楽しいことです。 Robin Rendleは、CSS-Tricksに関するこの将来のセレクターに関する追加の洞察を提供しました。
レベル3からの佳作:empty
セレクターレベル3で見逃した可能性のある便利な疑似クラスは、 :empty
です。これは、テキストノードを含む子要素がない場合に要素に一致します。
ルールp:empty
は<p></p>
に一致しますが、 <p>Hello</p>
には一致しません。
:empty
を使用する1つの方法は、JavaScriptが入力された動的コンテンツのプレースホルダーである可能性のある要素を非表示にすることです。 おそらく、検索結果を受け取るdivがあり、それが入力されると、境界線といくつかのパディングがあります。 しかし、まだ結果がないので、ページ上のスペースを占有することは望ましくありません。 :empty
を使用すると、次のように非表示にできます。
.search-results:empty { display: none; }
空の状態でメッセージを追加することを考えていて、疑似要素とcontent
を使用してメッセージを追加したいと思うかもしれません。 ここでの落とし穴は、 content
にアクセスできるかどうかに一貫性のない支援技術のユーザーがメッセージを利用できない可能性があることです。 つまり、 「結果なし」タイプのメッセージにアクセスできるようにするには、それを段落のような実際の要素として追加する必要があります(非表示のdivではaria-label
にアクセスできなくなります)。
セレクターについて学ぶためのリソース
CSSには、疑似クラスを含むさらに多くのセレクターがあります。 利用可能なものについてさらに学ぶためのいくつかの場所があります:
- MDN CSSセレクターのドキュメントには、包括的な分類リストが含まれています。
- 高度なCSSセレクターの2部構成のガイドを作成しました。第1部から始めることができます。
- ゲームCSSDinerでCSSセレクターについて楽しく学んでください。
- Kitty Giraudelは、提供されたセレクターの一部を分解して説明するセレクター説明ツールを作成しました。