この記事の目次
CSSコンテナクエリの使い方とは
コンテナクエリは、親要素(コンテナ)の大きさに応じてスタイルを切り替える機能です。メディアクエリ が「画面全体の幅」で判断するのに対し、コンテナクエリは「その部品が置かれた枠の幅」で判断します。同じカード部品を、メイン枠でもサイドバーでも、それぞれに合った形で表示できます。
MDNでは、2023年2月から広く使える Baseline の機能とされています(サイズに基づく問い合わせの場合。スタイルクエリなど一部の機能は対応状況が異なります)。
基本(構文・仕組み)
使い方は2段階です。まず、基準になる親要素に container-type を指定します。次に、子孫の要素に対して @container で条件を書きます。
.slot { container-type: inline-size; container-name: card; }
@container card (width >= 420px) {
.card { display: grid; grid-template-columns: 140px 1fr; }
}
| プロパティ | 役割 |
|---|---|
| container-type | inline-size(横幅を基準)、size(縦横)など |
| container-name | コンテナの名前。複数あるときに対象を絞れる |
| container | 名前 / タイプ の一括指定 |
条件に使われるのは「最も近い祖先のコンテナ」です。名前を付ければ、遠い祖先のコンテナも指定できます。MDNには、コンテナの大きさを基準にする単位 cqw(幅の1%)、cqi、cqb なども載っています。
サンプルコード(実行結果つき)
メイン枠(2fr)とサイド枠(1fr)に、同じカード部品を置いた例です。
<div class="layout">
<div class="slot"><div class="card"><div class="thumb"></div>
<div><h2>メイン枠のカード</h2><p>同じコンポーネントです。</p></div></div></div>
<div class="slot"><div class="card"><div class="thumb"></div>
<div><h2>サイド枠のカード</h2><p>同じコンポーネントです。</p></div></div></div>
</div>
.layout { display: grid; grid-template-columns: 2fr 1fr; gap: 16px; }
.slot { container-type: inline-size; container-name: card; }
.card { display: grid; gap: 8px; padding: 12px; border: 1px solid #cbd5e1; border-radius: 8px; }
.card .thumb { background: #93c5fd; height: 80px; border-radius: 6px; }
@container card (width >= 420px) {
.card { grid-template-columns: 140px 1fr; align-items: start; }
.card h2 { font-size: 1.25rem; }
}
@media (width < 600px) { .layout { grid-template-columns: 1fr; } }
画面幅が同じでも、枠の幅が420px以上なら横並び、未満なら縦並びになります。
動作確認(検証環境と結果)
- 環境: Windows 11、Microsoft Edge 154(Chromium系、headless)。ログは
C:Tempks2techtestscss-container-query.md。画面は目視しました。 - 結果(幅1200指定、実ビューポート1182px): メイン枠は756pxで、カードは2列(サムネイルと本文が横並び)。サイド枠は378pxで1列(縦並び)でした。
CSS.supports('container-type','inline-size')は true でした。 - 結果(幅390指定、headless最小幅の都合で実ビューポート504px): メディアクエリで1列になり、どちらの枠も472pxとなって、両方のカードが横並びになりました。画面が狭くても枠が広ければ横並びになる点が、メディアクエリと異なります。
- 未検証: 実機のスマートフォンでの表示、スタイルクエリ(
style())。
CSSコンテナクエリの使い方の注意点
container-type: inline-sizeを指定した要素は、横幅が子の内容に左右されなくなります(インラインサイズの封じ込め)。幅が内容次第で決まる配置(width: fit-contentなど)では、期待した幅にならないことがあります。- コンテナ自身のスタイルは、そのコンテナへの
@containerでは変更できません。必ず子孫のスタイルを変えます。 - 条件に使うのは、コンテナの幅です。画面の向きやホバーなど、端末の特性は メディアクエリ に任せます。
- 古いブラウザを広くサポートする案件では、対応状況を can I use で確認してください。
CSSコンテナクエリの使い方でよくあるミス
container-typeの指定を忘れて、@containerが効かない。- 条件を、コンテナ自身に書いてしまう。
container-type: sizeを指定して、高さがゼロになり、表示が消える。高さを持たせない通常の用途はinline-sizeです。- 名前の付け忘れで、意図しない祖先のコンテナが基準になる。
ブラウザ対応・バージョン
MDNの Baseline 表記では、サイズに関するコンテナクエリは2023年2月から広く使えます。cq 系の単位も同時期です。スタイルクエリやスクロール状態のクエリは対応状況が異なるため、最新はMDNの互換性表で確認してください。
CSSコンテナクエリの使い方のチェックリスト
- 基準にしたい親要素に
container-type: inline-sizeを指定したか。 @containerの中で変えるのは、子孫のスタイルか。- 必要なら
container-nameで対象を絞ったか。 - 画面全体で変える部分は、メディアクエリと役割分担したか。
- 部品を幅の違う場所に置いて、実際に確認したか。
CSSコンテナクエリの使い方のFAQ(よくある質問)
Q. メディアクエリはもう不要ですか?
A. 不要にはなりません。全体のレイアウト(ヘッダーの切り替えなど)や、ユーザー設定(動き・配色)にはメディアクエリが適しています。部品単位の切り替えにコンテナクエリを使うのが基本です。
Q. 高さで切り替えられますか?
A. container-type: size なら可能ですが、要素の高さが固定される制約があり、使い所は限られます。
Q. cqwはどんなときに便利ですか?
A. コンテナ幅に比例して文字を変える場合などに使えます。clamp() と組み合わせて上下限を付けると安全です。
筆者の見解(CSSコンテナクエリの使い方)
私見では、コンテナクエリは「部品を再利用する」設計と相性がよいと考えます。部品が自分の置かれた枠に合わせて形を変えれば、ページごとに上書きを書く必要がなくなります。ただし、全部をコンテナクエリにするより、ページ全体の骨格はメディアクエリ、部品の中身はコンテナクエリ、という分担が分かりやすいと思います。
