@container と :has(): 2 つの強力な新しいレスポンシブ API を Chromium 105 でリリース

コンテナクエリと :has() は、レスポンシブ ウェブデザインに最適な組み合わせです。幸い、これらの機能はどちらも Chromium 105 で同時にリリースされます。今回のリリースは、レスポンシブ インターフェース向けにリクエストの多かった 2 つの機能が追加された大規模なリリースです。

コンテナクエリ: 概要

コンテナ クエリを使用すると、デベロッパーは親セレクタのサイズとスタイル情報をクエリできるため、子要素がウェブページのどこにあっても、その子要素がレスポンシブ スタイル設定ロジックを所有できます。

デベロッパーは、入力のスタイル設定(利用可能なスペースなど)をビューポートに依存する代わりに、ページ内要素のサイズもクエリできるようになりました。この機能により、コンポーネントがレスポンシブ スタイル設定ロジックを所有することになります。これにより、コンポーネントがページのどこに表示されても、スタイル設定ロジックがコンポーネントに適用されるため、コンポーネントの復元力が大幅に向上します。

コンテナクエリの使用

コンテナ クエリを使用してビルドするには、まず親要素にコンテナ化を設定する必要があります。そのためには、親コンテナに container-type を設定します。次のような画像とテキスト コンテンツを含むカードがあるとします。

単一の 2 列カード。

コンテナクエリを作成するには、カードコンテナで container-type を設定します。

.card-container {
  container-type: inline-size;
}

container-typeinline-size に設定すると、親の行方向のサイズがクエリされます。英語などのラテン語では、テキストが左から右にインラインで流れるため、カードの幅になります。

これで、そのコンテナを使用して、@container を使用して子要素にスタイルを適用できるようになりました。

.card {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

@container (max-width: 400px) {
  .card {
    grid-template-columns: 1fr;
  }
}

:has() 親セレクタ

CSS :has() 疑似クラスを使用すると、親要素に特定のパラメータを持つ子要素が含まれているかどうかをデベロッパーが確認できます。

たとえば、p:has(span) は、内部に span を持つ段落(p)セレクタを示します。親段落自体のスタイルを設定したり、段落内の要素のスタイルを設定したりできます。たとえば、字幕を含む figure 要素のスタイルを設定する figure:has(figcaption) があります。:has() について詳しくは、Jhey Tompkins によるこちらの記事をご覧ください。

コンテナクエリと :has()

:has() の親の選択機能とコンテナクエリの親クエリの機能を使用して、非常に動的な組み込みスタイルを作成できます。

ロケットカードを使って、最初の例を拡張してみましょう。画像のないカードの場合はどうすればよいですか?画像なしでも意図的に見えるように、タイトルのサイズを大きくし、グリッド レイアウトを 1 列に調整することもできます。

カード上の大きなテキスト。画像なしで、列に表示されます。

この例では、画像を含むカードには 2 列のグリッド テンプレートがあり、画像のないカードには 1 列のレイアウトがあります。また、画像のないカードの見出しは大きくなります。:has() を使用してこれを記述するには、次の CSS を使用します。

.card:has(.visual) {
  grid-template-columns: 1fr 1fr;
}

上記の 2 列スタイルを適用するには、visual というクラスを持つ要素を探します。もう 1 つの優れた CSS 関数に :not() があります。これは :has() と同じ仕様の一部ですが、はるかに長い間使用されており、ブラウザのサポートも優れています。次のように、:has():not() を組み合わせることもできます。

.card:not(:has(.visual)) h1 {
  font-size: 4rem;
}

上記のコードでは、visual クラスを含まないカード内の h1 にスタイルを設定するセレクタを記述しています。このように、フォントサイズを明確に調整できます。

すべてを組み合わせる

上のデモでは、:has():not()@container の組み合わせを示していますが、コンテナクエリは、同じ要素が複数の場所で使用されている場合に真価を発揮します。スタイルを少し追加して、これらのカードをグリッド形式で並べて表示しましょう。

これで最新の CSS の威力を体感できます。ターゲット スタイルを使用すると、ロジックの上にロジックを構築し、非常に堅牢なコンポーネントを作成できるため、明確なスタイルを記述できます。これらの 2 つの強力な機能が Chromium 105 に導入され、クロスブラウザ サポートが勢いを増している今、UI デベロッパーにとって非常にエキサイティングな時代です。