はじめに
従来のレスポンシブデザインでは、メディアクエリを使ってビューポート(画面サイズ)に応じたスタイルを適用するのが一般的でした。しかし、この方法にはコンポーネント設計において大きな課題がありました。コンポーネントが配置される場所によって、同じビューポートでも親要素の幅が異なるケースに対応できないのです。
CSSコンテナクエリはこの課題を解決する技術です。親要素(コンテナ)のサイズに応じてスタイルを適用できるため、コンポーネントが「自分がどこに配置されているか」を認識して、適切なレイアウトに切り替わります。
本記事では、コンテナクエリについて以下の内容を解説します。
- コンテナクエリとは何か
container-typeとcontainer-nameプロパティの使い方@containerルールの構文と書き方- メディアクエリとの違いと使い分け
- コンポーネントベース設計との相性
前提条件
本記事を読み進めるにあたり、以下の知識があることを前提としています。
- CSSの基本構文(セレクタ、プロパティ、値)
- メディアクエリの基本的な書き方
- FlexboxまたはCSS Gridの基礎知識
動作確認環境
- Google Chrome 105以降
- Firefox 110以降
- Safari 16以降
- Microsoft Edge 105以降
コンテナクエリとは
コンテナクエリ(Container Queries)は、特定の親要素のサイズに基づいてスタイルを適用するCSS機能です。2023年に主要ブラウザで正式サポートされ、モダンCSSの重要な機能として定着しています。
メディアクエリとの本質的な違い
メディアクエリとコンテナクエリの違いを視覚的に理解しましょう。
flowchart TB
subgraph media["メディアクエリ"]
direction TB
V["ビューポート(画面全体)"]
V --> C1["コンポーネントA"]
V --> C2["コンポーネントB"]
V --> C3["コンポーネントC"]
end
subgraph container["コンテナクエリ"]
direction TB
P1["親要素1"] --> CC1["コンポーネントA"]
P2["親要素2"] --> CC2["コンポーネントB"]
P3["親要素3"] --> CC3["コンポーネントC"]
end| 比較項目 | メディアクエリ | コンテナクエリ |
|---|---|---|
| 参照する対象 | ビューポート(画面サイズ) | 親要素(コンテナ) |
| スコープ | グローバル | ローカル(コンポーネント単位) |
| 再利用性 | 配置場所に依存 | 配置場所に依存しない |
| 使用例 | ページ全体のレイアウト変更 | コンポーネントの内部レイアウト変更 |
なぜコンテナクエリが必要なのか
具体的なシナリオで考えてみましょう。カードコンポーネントを作成し、以下の3箇所に配置するケースを想定します。
- メインコンテンツエリア(幅広い)
- サイドバー(幅狭い)
- フッター(中程度の幅)
flowchart LR
subgraph page["ページレイアウト"]
direction TB
subgraph main["メインエリア(800px)"]
Card1["カード:横並びレイアウト"]
end
subgraph sidebar["サイドバー(300px)"]
Card2["カード:縦積みレイアウト"]
end
subgraph footer["フッター(500px)"]
Card3["カード:コンパクトレイアウト"]
end
endメディアクエリでは、画面幅が1200pxの場合、すべてのカードに同じスタイルが適用されます。しかしコンテナクエリを使えば、各カードが「自分の親要素の幅」に応じて最適なレイアウトを選択できます。
container-typeプロパティ
コンテナクエリを使用するには、まず親要素をコンテナとして定義する必要があります。container-typeプロパティを使用して、要素をクエリコンテナに指定します。
基本構文
|
|
指定可能な値
| 値 | 説明 |
|---|---|
normal |
コンテナサイズクエリの対象外(デフォルト値) |
inline-size |
インライン方向(横書きでは幅)のサイズクエリが可能 |
size |
インライン方向とブロック方向の両方のサイズクエリが可能 |
実務ではinline-sizeを使用するケースがほとんどです。sizeを指定すると、要素は高さ方向にもコンテインメント(封じ込め)が適用されるため、子要素による高さの自動調整ができなくなります。
使用例
|
|
|
|
この設定により、.post要素がクエリコンテナとなり、その子孫要素に対してコンテナクエリを適用できるようになります。
container-nameプロパティ
複数のコンテナが存在する場合、特定のコンテナを識別するために名前を付けることができます。
基本構文
|
|
名前付きコンテナのメリット
名前を付けることで、以下のメリットが得られます。
- 明確な対象指定:どのコンテナを参照しているか明確になる
- 祖先コンテナの指定:直近の親だけでなく、特定の祖先コンテナを対象にできる
- コードの可読性向上:意図が明確になり、メンテナンスしやすくなる
複数の名前を付ける
1つのコンテナに複数の名前を付けることも可能です。
|
|
containerショートハンドプロパティ
container-typeとcontainer-nameは、containerプロパティでまとめて指定できます。
構文
|
|
使用例
|
|
ショートハンドを使用することで、コードがより簡潔になります。
@containerルールの書き方
コンテナを定義したら、@containerルールを使って条件付きスタイルを記述します。
基本構文
|
|
幅による条件指定
|
|
名前付きコンテナへのクエリ
特定のコンテナを対象にする場合は、名前を指定します。
|
|
複数条件の組み合わせ
論理演算子を使って複数の条件を組み合わせられます。
|
|
範囲構文
メディアクエリと同様に、範囲構文も使用できます。
|
|
実践的な使用例
実際のコンポーネント設計でコンテナクエリを活用する例を見ていきましょう。
レスポンシブカードコンポーネント
配置場所に応じてレイアウトが変わるカードコンポーネントを実装します。
|
|
|
|
ナビゲーションメニュー
コンテナの幅に応じてメニューの表示形式を切り替えます。
|
|
|
|
コンテナクエリの長さ単位
コンテナクエリでは、コンテナのサイズに相対的な長さ単位を使用できます。
| 単位 | 説明 |
|---|---|
cqw |
コンテナの幅の1% |
cqh |
コンテナの高さの1% |
cqi |
コンテナのインラインサイズの1% |
cqb |
コンテナのブロックサイズの1% |
cqmin |
cqiとcqbのうち小さい方 |
cqmax |
cqiとcqbのうち大きい方 |
使用例
|
|
これらの単位を使うことで、よりきめ細かいレスポンシブ調整が可能になります。
メディアクエリとの使い分け
コンテナクエリとメディアクエリは競合する技術ではなく、それぞれ適した用途があります。
メディアクエリを使うべきケース
- ページ全体のレイアウト構造を変更する場合
- グローバルなスタイル(フォントサイズ、余白など)を調整する場合
- デバイスの特性(解像度、向き、ホバー対応など)を判定する場合
|
|
コンテナクエリを使うべきケース
- 再利用可能なコンポーネントの内部レイアウトを調整する場合
- コンポーネントが配置される場所に依存しないスタイルを実装する場合
- デザインシステムやUIライブラリを構築する場合
|
|
組み合わせて使う
実際のプロジェクトでは、両者を組み合わせて使用するのが効果的です。
|
|
コンポーネントベース設計との相性
コンテナクエリは、ReactやVue.jsなどのコンポーネントベースフレームワークと非常に相性が良い技術です。
コンポーネントの独立性向上
コンテナクエリを使用することで、コンポーネントは自己完結的になります。
flowchart TB
subgraph before["従来のアプローチ"]
direction TB
Page1["ページA"]
Page2["ページB"]
Card1["カードコンポーネント"]
Page1 -.->|".page-a .card { ... }"| Card1
Page2 -.->|".page-b .card { ... }"| Card1
end
subgraph after["コンテナクエリ"]
direction TB
Page3["ページA"]
Page4["ページB"]
Card2["カードコンポーネント<br/>(自己完結)"]
Page3 --> Card2
Page4 --> Card2
end従来は親要素のクラス名に依存したスタイル(.sidebar .cardなど)を書く必要がありましたが、コンテナクエリでは不要です。
デザインシステムへの適用
デザインシステムでコンテナクエリを活用する際の設計パターンを紹介します。
|
|
|
|
この設計により、コンポーネントを配置する際にdata属性を付与するだけで、適切なレスポンシブ動作が得られます。
ブラウザサポートと注意点
ブラウザサポート状況
コンテナクエリは2023年2月にすべての主要ブラウザでサポートされ、現在はBaseline Widely Availableの状態です。
| ブラウザ | サポートバージョン |
|---|---|
| Chrome | 105以降 |
| Edge | 105以降 |
| Firefox | 110以降 |
| Safari | 16以降 |
フォールバック戦略
古いブラウザのサポートが必要な場合は、@supportsを使ったフォールバックを実装できます。
|
|
パフォーマンスに関する考慮
コンテナクエリはcontainer-typeを指定した要素にCSS Containmentを適用します。これにより、ブラウザは再レンダリングの範囲を限定でき、パフォーマンス上のメリットがあります。
ただし、以下の点に注意が必要です。
container-type: sizeを使用すると、高さの自動計算ができなくなる- 過度に深いネストは避ける
- 必要な箇所にのみコンテナを定義する
おわりに
コンテナクエリは、コンポーネントベースの現代的なWeb開発において不可欠な技術です。メディアクエリがページ全体のレイアウトを制御するのに対し、コンテナクエリはコンポーネント単位でのレスポンシブ対応を可能にします。
本記事で解説した内容をまとめると、以下のようになります。
container-typeプロパティで要素をクエリコンテナに指定するcontainer-nameで名前を付けて特定のコンテナを識別する@containerルールで条件に応じたスタイルを適用する- メディアクエリとコンテナクエリは用途に応じて使い分ける
- コンポーネントベース設計と組み合わせることで、再利用性の高いUIを構築できる
コンテナクエリを活用することで、配置場所に依存しない、真にポータブルなコンポーネントを実装できます。デザインシステムの構築やUIライブラリの開発において、ぜひ活用してください。