新しくサポートされた最新のCSS疑似クラスセレクターのガイド

公開: 2022-03-10
簡単な要約↬CSSワーキンググループエディターのセレクターレベル4のドラフトには、最新のブラウザーのほとんどにプロポーザル候補が既にあるいくつかの疑似クラスセレクターが含まれています。 このガイドでは、現在最高のサポートを提供しているものと、それらを今日使用し始める方法を示す例を取り上げます。

疑似クラスセレクターは、コロン文字「 : 」で始まり、現在の要素の状態に基づいて一致するセレクターです。 状態は、ドキュメントツリーに相対的である場合もあれば、 :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は次のとおりです。

StephanieEcklesによるペン[:focus-visibleのテストアプリケーション](https://codepen.io/smashingmag/pen/MWJZbew)を参照してください。

Stephanie Ecklesによる:focus-visibleの侵入テストアプリケーションを参照してください。

:focus-within

:focus-within疑似クラスは、最新のすべてのブラウザーでサポートされており、ほとんど親セレクターのように機能しますが、非常に特定の条件に対してのみ機能します。 包含要素にアタッチされ、子要素が:focusに一致する場合、スタイルを包含要素コンテナ内の他の要素に追加できます。

この動作を使用するための実用的な拡張機能は、関連する入力にフォーカスがある場合のフォームラベルのスタイル設定です。 これを機能させるには、ラベルをラップしてコンテナに入力し、そのコンテナに:focus-withinをアタッチして、ラベルを選択します。

 .form-group:focus-within label { color: blue; }

これにより、入力にフォーカスがあるときにラベルが青色に変わります。

このCodePenデモには、 .form-groupコンテナに直接アウトラインを追加することも含まれています。

StephanieEcklesによるペン[:focus-withinのテストアプリケーション](https://codepen.io/smashingmag/pen/xxgmREq)を参照してください。

Stephanie Ecklesによる:focus-withinの侵入テストアプリケーションを参照してください。

:is()

「任意のマッチ」疑似クラスとも呼ばれる:is()は、セレクターのリストを取得して、マッチングを試みることができます。 たとえば、見出しのスタイルを個別に一覧表示する代わりに、 :is(h1, h2, h3)のセレクターの下でそれらをグループ化できます。

:is()セレクターリストに関するいくつかの固有の動作:

  • リストされたセレクターが無効な場合、ルールは引き続き有効なセレクターと一致します。 :is(-ua-invalid, article, p)与えられると、ルールはarticlepに一致します。
  • 計算された特異性は、最も高い特異性を持つ渡されたセレクターの特異性と等しくなります。 たとえば、 :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()をさらにテストできます。

StephanieEcklesによるペン[Testing`:where()`の特異性](https://codepen.io/smashingmag/pen/jOyXVMg)を参照してください。

Stephanie Ecklesによるペネトレーションテスト: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の子孫ではないリンクを選択することでこの機能を示しています。

Stephanie Ecklesによるペン[子孫セレクターを使用した:not()のテスト](https://codepen.io/smashingmag/pen/BapvQQv)を参照してください。

Stephanie Ecklesによる子孫セレクターを使用した侵入テスト:not()を参照してください。

ボーナス:前のデモには、 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は、提供されたセレクターの一部を分解して説明するセレクター説明ツールを作成しました。