Tech
Container Queries で幅を判断する
このカードは、画面幅を一切見ていません。自分が入っている箱の幅だけを見てレイアウトを切り替えます。
メディアクエリは画面の話しかできません。同じカードを本文カラムとサイドバーの両方で使うと、そこで破綻します。
HTML は 2 つとも同一です。違うのは外側の箱の幅だけ。狭い箱では縦積み、広い箱では横並びになります。
240px
このカードは、画面幅を一切見ていません。自分が入っている箱の幅だけを見てレイアウトを切り替えます。
520px
このカードは、画面幅を一切見ていません。自分が入っている箱の幅だけを見てレイアウトを切り替えます。
ブラウザの幅は変えていません。変えたのは箱の幅だけです。メディアクエリでは、この 2 つを同時に成立させられません。
下の箱は右下の角をドラッグすると横幅を変えられます(resize: horizontal。これも CSS だけです)。420px を越えたところでレイアウトが切り替わります。
このカードは、画面幅を一切見ていません。自分が入っている箱の幅だけを見てレイアウトを切り替えます。
.cq-box { container-type: inline-size; }
.cq-card { display: grid; gap: 12px; } /* 既定は縦積み */
@container (min-width: 420px) { /* 画面ではなく箱の幅 */
.cq-card { grid-template-columns: 120px 1fr; align-items: center; }
} | 観点 | Container Queries | ResizeObserver + class 付け替え |
|---|---|---|
| 追加する JS | 0 行 | 要素ごとの監視と解除の管理 |
| 初回描画 | CSS 解決時点で確定 | スクリプト実行まで 1 フレーム遅れる(ちらつき) |
| コンポーネントの再利用 | 置いた場所が自分で決まる | 置く側が幅を知らせる必要がある |
| 未対応時 | 既定の縦積みのまま(読める) | スクリプトが落ちると縦積みのまま |
container-type を付けた要素の中身しか反応しません。カードそのものにコンテナを付けて、そのカードの見た目を変えることはできない。ラッパーが 1 枚必要です。
container-type: size は高さも封じ込めるため、中身で高さが決まる箱では潰れます。基本は inline-size です。
未対応ブラウザには @container ブロックが届きません。既定を縦積みにしておけば、届かなくても読める状態が残ります。
3 つの中で唯一、動きの好みが関係しません。壊れ方も「昔のレイアウトのまま」で済みます。記事カードを本文とサイドバーで使い回すときに、そのまま効きます。