CSS コンテナクエリ(@container)の基本的な使い方
2023年2月に主要ブラウザに対応したコンテナクエリ(CSS container queries)の基本的な使い方についての覚書です。
作成日:2024年4月9日
コンテナクエリとは
コンテナクエリとは、親要素や祖先要素に基づいてスタイルを定義できる CSS の新しい機能です。
以下は MDN の「コンテナーのサイズおよびスタイルクエリーの使用」からの抜粋です。
コンテナクエリはメディアクエリと似ています。
@media アットルールは、ビューポートのサイズや端末のその他の特性に基づいて要素にスタイル設定を適用します。
同様に、 @container アットルールは、ビューポートではなく、コンテナ要素のサイズやその他のスタイル特性に基づいて要素にスタイルを適用します。
コンテナクエリにはコンテナサイズクエリとコンテナスタイルクエリの2種類があります。
-
- コンテナ サイズ クエリ
- コンテナ要素の現在のサイズに基づいて要素にスタイルを適用するコンテナクエリ
-
- コンテナ スタイル クエリ
- コンテナ要素のスタイル機能に基づいて要素にスタイルを適用するコンテナクエリ。※ 現時点ではブラウザのサポートは限定的です(以下では扱っていません)
例えば、以下の HTML がある場合、コンテナクエリを使って ul 要素のスタイルをその親要素の幅に応じて簡単に切り替えることができます。
ul 要素の親要素の幅に応じてスタイルを適用させるので、.list-wrapper を基準となるコンテナ要素とします。それには .list-wrapper に container-type プロパティを設定します。
.list-wrapper の幅に応じてスタイルを適用するので container-type
に inline-size
を指定します。
これにより、ブラウザは .list-wrapper がコンテナ要素であることと、その幅(inline-size)を対象としていることを認識してくれます。
そして、@container
ルールでコンテナクエリを定義します。
以下ではサイズ特性 width と比較演算子を使って幅が 500px 以上というクエリとそれにマッチした場合に適用するスタイルを設定しています。
これで、.list-wrapper の幅が500px以上の場合、その子孫の ul 要素に上記のスタイルが適用されます。
以下は上記コードの動作確認サンプルです。
ブラウザの幅を変更して .list-wrappe の幅が変化すると、.list-wrapper の幅が500pxでリストのスタイルが切り替わります。
- HTML
- CSS
- JavaScript
- TypeScript
- PHP
@container (width >= 500px) は @container (min-width: 500px)と同じことです(比較演算子)。
サポート状況
現時点(2024/04)では MDN のドキュメントで Baseline 2023 NEWLY AVAILABLE となっていて、「2023年2月以降、この機能は最新のデバイスとブラウザーのバージョンで動作します。 この機能は、古いデバイスやブラウザでは動作しない可能性があります」とあります。
各ブラウザのサポート状況の詳細は以下で確認できます。
https://caniuse.com/?search=container
以下は コンテナスタイルクエリ(CSS Container Style Queries)のサポート状況です。
参考情報
コンテナクエリのドキュメントやプロパティ、仕様については以下で確認できます。
基本的な使い方
コンテナクエリの使い方をまとめると以下のようになります。
-
- 基準となるコンテナ要素を決める
-
基準となるコンテナ要素は、スタイルを適用する要素の親要素や祖先要素になります。
基準となる適当な要素がない場合は作成します。
-
- 基準となるコンテナ要素でコンテナコンテキストを宣言
-
基準となるコンテナ要素に container-type プロパティで、対象とするサイズの種類を指定します。
基準となるコンテナ要素の横幅(インライン方向のサイズ)に応じてスタイルを適用する場合は、container-type に inline-size を指定します。
オプショナルで container-name プロパティを使って名前を付けることができます。
また、container プロパティを使うと container-type と container-name を一括指定できます。
container-type や container を設定することを「コンテナコンテキストを宣言する」と言います。また、それらが設定された要素は「コンテナコンテキストを持つ」などと言います。
-
- @container ルールでコンテナクエリを定義
-
@container ルールを使って条件と、条件にマッチした場合に適用するスタイルを設定します。
例えば、以下の HTML で .foo-wrapper のサイズに基づいて .foo やその子要素にスタイルを適用する場合、基準となるコンテナ要素は .foo-wrapper になります。
基準となるコンテナ要素に container-type プロパティを設定して、コンテナコンテキスト(その要素が基準となるコンテナであることとどのサイズを対象とするか)を宣言します。
これでブラウザは .foo-wrapper の幅(inline-size)の変更に反応するようになります。
例えば、.foo-wrapper の幅が 400px 以上の場合に .foo に背景色を設定するには以下のように @container を使ってコンテナクエリを記述します。
デバッグ(確認)用に resize プロパティを追加
開発段階で、基準となるコンテナ要素をリサイズ可能にしておくとコンテナクエリの動作を確認するのに便利です。
要素をリサイズ可能にするには、resize プロパティにその方向(水平方向の場合は horizontal)と、overflow プロパティに visible 以外を指定します。
以下は、上記のように.foo-wrapper に確認用の resize プロパティを追加して、初期値として幅 200px を設定したサンプルです。
foo
Lorem ipsum, dolor sit amet consectetur adipisicing elit.
※ resize プロパティは iPhone などではサポートされていません。
https://caniuse.com/css-resize
特定の要素の親要素をコンテナにする
:has() を使って、*:has(> セレクタ)
のように特定のセレクタの直接の親要素を基準となるコンテナ要素とすることができます。
但し、この場合、意図しない要素が基準となるコンテナ要素になる可能性もあるので注意が必要です。
Lorem ipsum, dolor sit amet consectetur adipisicing elit.
基準となるコンテナ要素
基準となるコンテナ要素自身にはコンテナクエリを指定できません。
コンテナクエリで基準となるコンテナ要素自身 にスタイルを指定しても機能しません(無効です)。
但し、基準となるコンテナ要素の擬似要素(::before など)にスタイルを指定することはできます。
プロパティ
container-type
container-type では、基準となるコンテナ要素の対象とするサイズ(コンテナコンテキスト)を指定します。以下を指定することができます。
値 | 説明 |
---|---|
inline-size | インライン方向のサイズ(横幅)を対象とする |
size | インライン方向及びブロック方向のサイズを対象とする。※ size を指定する場合、基準となるコンテナ要素に height を指定する必要あります。 |
normal | コンテナサイズクエリーの基準となるコンテナ要素ではない(初期値)。 |
基準となるコンテナ要素の横幅に基づいてスタイルを適用する場合は、inline-size を指定します。
値に size を指定する例
inline-size を指定してコンテナ要素の幅に基づいてスタイルを適用することが多いと思いますが、コンテナクエリで条件(サイズ特性)に orientation や aspect-ratio を指定する場合は、container-type の値に size を指定して、インライン方向及びブロック方向のサイズを対象とする必要があります。
以下は基準となるコンテナ要素(.bar-wrapper)が縦長か横長により、子要素(.bar)の背景色を切り替える例です。
※ container-type: size を指定した場合、基準となるコンテナ要素に height を指定しないと表示されないので注意が必要です。
container-name
container-name プロパティを使って、コンテナを識別するための名前を付けることができます。
名前を付けると、その名前を @container で使用することができ、特定のコンテナを対象とすることができます。
名前を指定しない場合には、コンテナコンテキストを持つ(container-type を指定した)最も近い祖先要素が対象になります。
任意の名前を付けることができますが、大文字と小文字は区別され、また、以下の条件があります。
- 名前の値は引用符で囲んではいけない
- スペースで区切られた複数の名前のリストを指定できます
@container で使用する際は、@container の後に名前を指定します。
container
container プロパティは container-name と container-type を一括指定するためのショートハンドプロパティで、コンテナ名 / コンテナタイプ
のように値を /
で区切って指定します。
例えば、以下は
以下のようにまとめて記述できます。
@container ルール
@container はコンテナに対して評価される特性(条件)を指定してスタイルを適用するルールです。
以下が構文です。
- 条件:コンテナのサイズが変更されたときに、コンテナに対して評価される特性の集合
- CSS:指定した条件が真であれば(マッチすれば)適用されるスタイル
論理キーワード
コンテナクエリの条件では論理演算子の and と or 及び not が使えます。但し、コンテナクエリあたり1つの not だけが許されており、 and または or キーワードと同時に使用することはできません。
比較演算子
サイズ特性クエリで比較演算子(=、<、<=、>、>=)が使用できます。
例えば、以下の min-、max- 接頭辞を使用した記述は
以下のように比較演算子を使って記述することができます。
また、比較演算子を使って以下のような記述も可能です。
Media Queries Level 4 より、メディアクエリでも比較演算子(=、<、<=、>、>=)が使用できるようになっています(https://caniuse.com/css-media-range-syntax)。
サイズ特性
コンテナクエリで指定できるサイズ特性の記述子は以下になります。
記述子 | 説明 |
---|---|
width | 横幅 |
height | 高さ |
inline-size | インラインサイズ(横書きでは水平方向、縦書きでは垂直方のサイズ) |
block-size | ブロックサイズ(横書きでは垂直方向、縦書きでは水平方向のサイズ) |
aspect-ratio | アスペクト比 |
orientation | portrait(縦長)または landscape(横長) |
コンテナクエリの長さ単位
コンテナクエリでスタイルを設定する場合、以下のコンテナクエリの長さ単位(クエリするコンテナのサイズに相対する長さ)を使用することができます。
これらを使用することで、基準となるコンテナ要素の幅や高さに応じたサイズ指定が可能です。
単位 | 説明 |
---|---|
cqw | 基準となるコンテナ要素の幅の 1% |
cqh | 基準となるコンテナ要素の高さの 1% |
cqi | 基準となるコンテナ要素のインラインサイズの 1% |
cqb | 基準となるコンテナ要素のブロックサイズの 1% |
cqmin | cqi または cqb の小さい方 |
cqmax | cqi または cqb の大きい方 |