判定: 採用

カード自身が幅を判断する

メディアクエリは画面の話しかできません。同じカードを本文カラムとサイドバーの両方で使うと、そこで破綻します。

デモ 1: 同じカードを、幅の違う箱に 2 つ入れる

HTML は 2 つとも同一です。違うのは外側の箱の幅だけ。狭い箱では縦積み、広い箱では横並びになります。

240px

Tech

Container Queries で幅を判断する

このカードは、画面幅を一切見ていません。自分が入っている箱の幅だけを見てレイアウトを切り替えます。

520px

Tech

Container Queries で幅を判断する

このカードは、画面幅を一切見ていません。自分が入っている箱の幅だけを見てレイアウトを切り替えます。

ブラウザの幅は変えていません。変えたのは箱の幅だけです。メディアクエリでは、この 2 つを同時に成立させられません。

デモ 2: 自分で幅を引っぱってみる

下の箱は右下の角をドラッグすると横幅を変えられます(resize: horizontal。これも CSS だけです)。420px を越えたところでレイアウトが切り替わります。

Tech

Container Queries で幅を判断する

このカードは、画面幅を一切見ていません。自分が入っている箱の幅だけを見てレイアウトを切り替えます。

.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; }
}

JavaScript で書いた場合との比較

観点Container QueriesResizeObserver + class 付け替え
追加する JS0 行要素ごとの監視と解除の管理
初回描画CSS 解決時点で確定スクリプト実行まで 1 フレーム遅れる(ちらつき)
コンポーネントの再利用置いた場所が自分で決まる置く側が幅を知らせる必要がある
未対応時既定の縦積みのまま(読める)スクリプトが落ちると縦積みのまま

実運用で使うときの注意

コンテナ自身は問い合わせ対象にできない

container-type を付けた要素の中身しか反応しません。カードそのものにコンテナを付けて、そのカードの見た目を変えることはできない。ラッパーが 1 枚必要です。

inline-size 以外は副作用が大きい

container-type: size は高さも封じ込めるため、中身で高さが決まる箱では潰れます。基本は inline-size です。

既定を「狭いほう」にする

未対応ブラウザには @container ブロックが届きません。既定を縦積みにしておけば、届かなくても読める状態が残ります。

判定を「採用」にした理由

3 つの中で唯一、動きの好みが関係しません。壊れ方も「昔のレイアウトのまま」で済みます。記事カードを本文とサイドバーで使い回すときに、そのまま効きます。