レスポンシブの実装が今までと変わる! CSSの新機能コンテナクエリと:has()疑似クラス、最初に理解しておきたい基礎知識を解説
Post on:2022年8月25日
CSSの新機能コンテナクエリ(@container
)と:has()
疑似クラスが、いよいよChrome 105(8月末、来週リリース予定)でサポートされます。
コンテナクエリとは今までのメディアクエリがビューポートに依存していたのとは異なり、親要素(コンテナ)のサイズに対してスタイルを適用できます。:has()
疑似クラスは指定した要素を含んでいる場合にスタイルを適用できます。
レスポンシブの実装この2つの新機能は単独でも強力ですが、組み合わせるとさらにすごいパワーを発揮します。この2つの新機能の最初に理解しておきたい基礎知識を紹介します。
container and :has(): two powerful new responsive APIs landing in Chromium 105
by Una Kravets
下記は各ポイントを意訳したものです。
※元サイト様のライセンスにもとづいて翻訳しています。
はじめに
コンテナクエリ(@container
)と:has()
疑似クラスは、レスポンシブにおける素晴らしい組み合わせです。幸いなことに、この2つの新機能はChrome 105で同時に使用できるようになります。
これはレスポンシブのUIデザインに強く要望されていた、大きなリリースです!
【訳者注】
Chrome 105はベータ版が8/8にリリースされ、安定版は8月末予定です。
参考: Chrome Roadmap
コンテナクエリと:has()
疑似クラスについて、詳しく知りたい方は以前の記事もご覧ください。
- CSS コンテナクエリの基礎知識と便利な使い方を解説
- CSSの新機能コンテナクエリのポリフィルがこれほど使いやすく、Googleから提供されたことは素晴らしい
- CSSの:has()疑似クラスの便利な使い方を徹底解説
コンテナクエリとは
コンテナクエリを使用すると、デベロッパーは親セレクタにそのサイズとスタイル情報をクエリすることができます。これにより、子要素はWebページ上のどこにあってもレスポンシブに対応したスタイルを適用することが可能になります。
利用可能なスペースのスタイルをビューポートに依存する代わりに、ページ内の要素のサイズをクエリできるようになります。この機能は、コンポーネント自体にレスポンシブに対応するためのスタイルのロジックを持たせることができることを意味します。つまり、そのコンポーネントはページ上のどこに配置されてもスタイルのロジックが適用されるため、コンポーネントの弾力性は大幅に向上します。
コンテナクエリは現在、ChromiumとSafari TPでサポートされています。
※Chromeの次期バージョン105でサポート予定。
コンテナクエリの使い方
コンテナクエリを使用するには、まず親要素にコンテナを設定する必要があります。これは簡単で、container-type
プロパティを設定するだけです。
たとえば、下記のように画像とテキストを含むカードがあるとします。
画像とテキストを含むカード
コンテナクエリを使用するには、コンテナにcontainer-type
を設定します。
1 2 3 |
.card-container { container-type: inline-size; } |
container-type
をinline-size
にすると、親のインライン方向のサイズがクエリされます。英語のような言語では、テキストは左から右へインラインで流れるので、これはカードの幅になります。
次に@container
を使用して、コンテナ内の子要素にスタイルを適用します。
1 2 3 4 5 6 7 8 9 10 |
.card { display: grid; grid-template-columns: 1fr 1fr; } @container (max-width: 400px) { .card { grid-template-columns: 1fr; } } |
実際の動作はデモページでご覧ください。
See the Pen
Simple CQ Demo by web.dev (@web-dot-dev)
on CodePen.
:has()疑似クラスとは
CSSの:has()
擬似クラスは、親要素が特定のパラメータを持つ子を含んでいるかどうかを確認するためのものです。
たとえば、p:has(span)
は内部にspan
を含む段落(p
)セレクタを示します。これを使用して、親段落自体のスタイルを設定したり、その中の子要素のスタイルを設定できます。便利な例としてもう一つ、キャプションを含むfigure
要素のスタイルを設定するfigure:has(figcaption)
があります。詳しい使い方は、Jhey Tompkinsによる記事をご覧ください。
:has()
擬似クラスは現在、ChromiumとSafariでサポートされています。
※Chromeの次期バージョン105でサポート予定。
コンテナクエリと:has()疑似クラスの使い方
:has()
擬似クラスの親選択機能とコンテナクエリの親クエリ機能を組み合わせることで、非常にダイナミックな組み込みスタイルを実装できます。
前述のカードを拡張してみましょう。
画像のないカードがあったらどうでしょうか? タイトルのサイズを大きくして、グリッドをシングルカラムに変更すれば、画像なしでもよりよく表示されます。
上: 前述のカード、下: 画像なしのカード
この例では、画像ありのカードは2カラムのグリッド、画像なしのカードは1カラムのレイアウトになっています。さらに、画像のないカードではタイトルのサイズが大きくなっています。これを:has()
で実装するには、以下のCSSを使用します。
1 2 3 |
.card:has(.visual) { grid-template-columns: 1fr 1fr; } |
上の2段組のスタイルを適用するために、.visual
というクラスを持つ要素を探しています。CSSのもうひとつの便利な関数が:not()
です。これは:has()
と同じ仕様の一部ですが、ずっと前から存在しており、ブラウザのサポートも十分あります。そして、:has()
と:not()
を組み合わせることもできます。
1 2 3 |
.card:not(:has(.visual)) h1 { font-size: 4rem; } |
上記のCSSでは、.visual
を含まないカード内のh1
にスタイルを設定するセレクタを記述しています。こうすることで、フォントのサイズを非常に明確に変更することができます。
実際の動作はデモページでご覧ください。
See the Pen
Simple CQ Demo with :has() by web.dev (@web-dot-dev)
on CodePen.
すべてを一緒に使用すると
上記のデモでは:has()
と:not()
と@container
を組み合わせていますが、コンテナクエリは同じ要素が複数の場所で使用されていることがわかる場合に真価を発揮します。スタイルを少し追加して、カードをグリッドに並べてみましょう。
実際の動作はデモページでご覧ください。
See the Pen
Space Facts - CQ Demo with :has() (in grid) by web.dev (@web-dot-dev)
on CodePen.
モダンCSSの威力を実感していただけたと思います。ロジックの上にロジックを構築し、ターゲットスタイルを使用して明確なスタイルを記述し、非常に堅牢なコンポーネントを作成することができます。コンテナクエリと:has()
という2つの強力な新機能がChrome 105にサポートされ、ブラウザサポートが勢いが増している今、UIデベロッパーにとっては非常にエキサイティングな時期です!
sponsors