2026年7月30日

2026年7月30日

WordPressでCSSコンテナクエリ(@container)を使ってコンポーネントを設計する方法

CSSのコンテナクエリ(@container)を使うと、画面幅ではなく「その部品が置かれた枠の幅」に応じてレイアウトを切り替えられます。同じ記事カードをメインカラムでは横並び、サイドバーでは縦積みにする、といった出し分けがメディアクエリなしで書けるため、ブロックを自由に配置するWordPressと相性のよい手法です。この記事では、基本の書き方、クエリーループの記事カードに適用する具体例、子テーマやブロック単位でCSSを読み込む方法、幅が0になるなどのつまずきどころまでを説明します。

メディアクエリとの違い

メディアクエリ(@media (min-width: 768px))が見るのはブラウザの画面幅です。ところがWordPressでは、同じブロックがメインカラム、サイドバー、カラムブロックの中など、幅の違う場所に置かれます。画面幅が広くても、狭いサイドバーの中ではカードを縦積みにしたい。メディアクエリではこれを場所ごとのセレクターで書き分けるしかなく、配置を変えるたびにCSSの修正が必要でした。

コンテナクエリは、親要素を「コンテナ」として登録し、その幅を条件にして子要素のスタイルを切り替えます。部品自身が置かれた場所の広さに反応するので、どこに置いても破綻しにくい部品を作れます。

ブラウザの対応については、幅を条件にするサイズのコンテナクエリは主要ブラウザで使える状態になっています(2026年10月現在)。古いブラウザでは @container の中身が無視されるだけなので、後述するように「基本の見た目はクエリなしで成立させる」書き方にしておけば、表示が崩れることはありません。

基本の書き方

コンテナクエリは2つの部分からなります。

/* 1. 親要素をコンテナとして登録する */
.card-wrap {
	container-type: inline-size;
	container-name: card;
	/* 上の2行は container: card / inline-size; とまとめて書ける */
}

/* 2. コンテナの幅を条件にして、子孫要素のスタイルを変える */
@container card (min-width: 480px) {
	.card {
		display: grid;
		grid-template-columns: 200px 1fr;
		gap: 1rem;
	}
}

押さえておきたい点は次のとおりです。

  • 条件にできるのは祖先のコンテナ: @container の中で変えられるのは、コンテナの子孫要素です。コンテナに指定した要素そのものの見た目は、自分の幅を条件にして変えられません。そのため「外枠(コンテナ)」と「中身(スタイルを変える部品)」の2階層を用意します。
  • **inline-size を使う**: 横書きでは横幅を意味します。size を指定すると高さも条件にできますが、高さを中身から決められなくなるため、通常のレイアウトでは扱いにくくなります。
  • 名前は付けておく: container-name を省くと、いちばん近いコンテナが条件の対象になります。入れ子になったときに意図しないコンテナを見てしまわないよう、部品ごとに名前を付けると管理しやすくなります。
  • 範囲の書き方: (min-width: 480px) のほか、(width >= 480px) のような範囲の構文も使えます。

コンテナの幅に比例する単位 cqi(コンテナの横幅の1%)も使えます。見出しの文字サイズをカードの幅に合わせて変えたいときは、font-size: clamp(1rem, 0.85rem + 1.5cqi, 1.5rem); のように上限と下限を付けて使うと、極端な大きさになりません。

実例: クエリーループの記事カードに適用する

ブロックエディターのクエリーループで記事一覧を作ると、各記事は .wp-block-post-template の中の li.wp-block-post として出力されます。この li をコンテナにして、中のアイキャッチ画像とタイトルの並び方を切り替えます。クエリーループをグリッド表示にしても、サイドバーに置いても、各記事の枠の幅に応じて表示が変わります。

全部の一覧に適用すると影響範囲が広いので、クエリーループのブロックに追加CSSクラス(ブロックの設定サイドバーの「高度な設定」にある項目。表記はバージョンで変わることがあります)として cq-cards を付け、そのクラスの中だけに効かせます。

/* 各記事の枠をコンテナにする */
.cq-cards .wp-block-post {
	container: post-card / inline-size;
}

/* 基本(狭い枠): 画像の下にタイトルを縦積み */
.cq-cards .wp-block-post-featured-image img {
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
	object-fit: cover;
}

/* 枠が 520px 以上なら横並び */
@container post-card (min-width: 520px) {
	.cq-cards .wp-block-post > .wp-block-group {
		display: grid;
		grid-template-columns: minmax(160px, 40%) 1fr;
		align-items: start;
		gap: 1.25rem;
	}
	.cq-cards .wp-block-post-featured-image {
		margin-block: 0;
	}
}

/* 枠が 800px 以上なら抜粋を表示し、タイトルを大きく */
@container post-card (min-width: 800px) {
	.cq-cards .wp-block-post-title {
		font-size: clamp(1.25rem, 1rem + 1cqi, 1.75rem);
	}
}

@container post-card (max-width: 799px) {
	.cq-cards .wp-block-post-excerpt {
		display: none;
	}
}

ここでは、投稿テンプレートの中にグループブロックを1つ置き、その中にアイキャッチ画像・タイトル・抜粋を並べた構成を想定しています。テーマやパターンによってブロックの入れ子が違うので、開発者ツールで実際のHTMLを確認し、セレクターを合わせてください。

アイキャッチ画像は aspect-ratio で縦横比を先に決めているため、画像の読み込み前後で高さが変わらず、レイアウトのずれ(CLS)を防げます。WordPressが出力する画像には srcset と sizes が付くので、カード幅に合ったサイズの画像が選ばれます。

CSSの読み込み方: 子テーマとブロック単位

CSSは子テーマに置きます。親テーマを直接編集すると、テーマの更新で消えてしまいます。

クラシックテーマの子テーマであれば、子テーマの style.css に書くか、別ファイルにして wp_enqueue_style() で読み込みます。特定のブロックが使われたページでだけ読み込みたい場合は、wp_enqueue_block_style() が便利です。

<?php
// 子テーマの functions.php
add_action( 'init', function () {
	wp_enqueue_block_style(
		'core/post-template',
		array(
			'handle' => 'my-cq-cards',
			'src'    => get_stylesheet_directory_uri() . '/css/cq-cards.css',
			'path'   => get_stylesheet_directory() . '/css/cq-cards.css',
			'ver'    => filemtime( get_stylesheet_directory() . '/css/cq-cards.css' ),
		)
	);
} );

wp_enqueue_block_style() は WordPress 5.9 で追加された関数で、ブロックテーマでは指定したブロックがページにあるときだけCSSを出力します。path を指定すると、小さなファイルはインラインで出力されることがあります。エディター側にも同じスタイルが読み込まれるので、編集画面でもコンテナクエリの効き方を確認できます。

ブロックテーマで手軽に試すなら、サイトエディターのスタイル設定にある追加CSSの欄に書く方法もあります。ただし、ここに書いた内容はデータベース(グローバルスタイル)に保存され、テーマのファイルとは別に管理されます。本番で長く使うCSSは、変更履歴を追えるように子テーマのファイルにまとめておくのがおすすめです。

つまずきやすいポイント

コンテナにした要素の幅が0になる・縮む: container-type: inline-size を指定すると、その要素の横幅は中身から決まらなくなります。親がフレックスボックスで幅の指定がない、display: inline-block や float、position: absolute で中身に合わせた幅になっている、といった場面では、幅が0や想定外の狭さになります。コンテナにする要素には、グリッドの列やブロック要素のように、外側から幅が決まる要素を選ぶか、width や flex-basis を指定してください。

クエリが効かない: 次の順に確認します。

  1. 開発者ツールで、スタイルを変えたい要素の祖先に container-type が付いているか(Chromeなどの開発者ツールでは、コンテナになっている要素の横に目印が表示されます)
  2. @container の名前とコンテナの container-name が一致しているか
  3. 条件の幅が、実際のコンテナの幅(パディングを除いた中身の幅)と合っているか
  4. キャッシュプラグインやCDNが古いCSSを配信していないか

エディターとフロントで見た目が違う: ブロックエディターではブロックの周りに余白や枠が追加されるため、コンテナの幅が少し狭くなります。境界の幅ちょうどに調整すると、エディターでだけ表示が切り替わる、ということが起きるので、境界値には余裕を持たせます。

スタイルクエリは様子見: コンテナのカスタムプロパティを条件にする @container style(--variant: compact) という書き方もありますが、対応ブラウザがまだ揃っていません(2026年10月現在)。本番の主要なレイアウトはサイズのクエリで組み、スタイルクエリは補助的な演出にとどめるのが安全です。

まとめ

  • コンテナクエリは、画面幅ではなく部品が置かれた枠の幅でレイアウトを切り替える仕組みです。
  • 外枠に container: 名前 / inline-size; を指定し、@container 名前 (min-width: …) で中の部品のスタイルを変えます。
  • クエリーループでは li.wp-block-post をコンテナにすると、グリッドでもサイドバーでも記事カードが枠に合わせて切り替わります。
  • CSSは子テーマに置き、ブロック単位で読み込みたい場合は wp_enqueue_block_style() を使います。
  • コンテナにした要素は中身から幅が決まらなくなるため、外側から幅が決まる要素を選びます。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲