CSSコンテナクエリ完全ガイド:コンポーネントレベルレスポンシブデザインの究極の解決策
前端工程(更新: 2026年6月2日)
コンテナクエリ:レスポンシブデザインのパラダイムシフト
従来のメディアクエリはビューポート幅に基づき、コンテナクエリは親コンテナ幅に基づきます—この一見小さな違いが、コンポーネントの再利用性を根本的に変えます。
| 次元 | メディアクエリ | コンテナクエリ |
|---|---|---|
| 参照対象 | ビューポート | 親コンテナ |
| 再利用性 | コンポーネントがページレイアウトに依存 | コンポーネントが完全に独立 |
| サイドバーシナリオ | 追加のブレークポイントが必要 | 自動適応 |
| ネストコンポーネント | 親を感知できない | ネイティブサポート |
| ブラウザサポート | すべて | Chrome 105+, Firefox 110+, Safari 16+ |
基本構文
コンテナの定義
.card-container {
container-type: inline-size;
container-name: card;
}
/* 省略形 */
.card-container {
container: card / inline-size;
}
container-typeの値:
| 値 | 意味 | クエリ可能な次元 |
|---|---|---|
inline-size |
インライン方向コンテナ | 幅 |
size |
二軸コンテナ | 幅 + 高さ |
normal |
コンテナではない(デフォルト) | なし |
コンテナクエリの記述
@container card (min-width: 400px) {
.card {
flex-direction: row;
}
.card-title {
font-size: 1.5rem;
}
}
@container card (max-width: 399px) {
.card {
flex-direction: column;
}
.card-title {
font-size: 1.2rem;
}
}
実践例:アダプティブカードコンポーネント
HTML構造
<div class="sidebar">
<div class="card-container">
<article class="card">
<img class="card-img" src="photo.jpg" alt="">
<div class="card-body">
<h3 class="card-title">記事タイトル</h3>
<p class="card-desc">記事の概要</p>
<span class="card-tag">フロントエンド</span>
</div>
</article>
</div>
</div>
<div class="main-content">
<div class="card-container">
<article class="card">
<!-- 同じカードコンポーネント -->
</article>
</div>
</div>
CSS実装
.card-container {
container: card / inline-size;
}
.card {
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1rem;
}
.card-img {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
border-radius: 0.5rem;
}
/* コンテナ幅 > 400px:水平レイアウト */
@container card (min-width: 400px) {
.card {
flex-direction: row;
align-items: center;
}
.card-img {
width: 200px;
aspect-ratio: 1;
flex-shrink: 0;
}
.card-title {
font-size: 1.25rem;
}
}
/* コンテナ幅 > 600px:大型カードレイアウト */
@container card (min-width: 600px) {
.card-img {
width: 280px;
}
.card-title {
font-size: 1.5rem;
}
.card-desc {
-webkit-line-clamp: 3;
}
}
効果:同じ.cardコンポーネントが、300pxのサイドバーでは自動的に縦並び、700pxのメイン領域では自動的に横並び—メディアクエリは一切不要です。
コンテナクエリ単位
vw/vhに似ていますが、ビューポートではなくコンテナを参照します:
| 単位 | 参照 | 等価関係 |
|---|---|---|
cqw |
コンテナ幅の1% | 1cqw = コンテナ幅 × 1% |
cqh |
コンテナ高さの1% | 1cqh = コンテナ高さ × 1% |
cqi |
コンテナインラインサイズの1% | cqwと等しい(水平書字モード) |
cqb |
コンテナブロックサイズの1% | cqhと等しい(水平書字モード) |
cqmin |
min(cqi, cqb) | 小さい方の値 |
cqmax |
max(cqi, cqb) | 大きい方の値 |
.card-title {
font-size: clamp(1rem, 3cqw, 2rem);
padding: 2cqw;
}
実践例:レスポンシブナビゲーションバー
.nav-container {
container: nav / inline-size;
}
.nav {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
/* 狭いコンテナ:ハンバーガーメニュー */
@container nav (max-width: 500px) {
.nav-links {
display: none;
}
.nav-hamburger {
display: block;
}
}
/* 中程度のコンテナ:水平ナビゲーション */
@container nav (min-width: 501px) {
.nav-links {
display: flex;
gap: 1rem;
}
.nav-hamburger {
display: none;
}
}
/* 広いコンテナ:ナビゲーション + 検索ボックス */
@container nav (min-width: 800px) {
.nav-search {
display: flex;
}
}
メディアクエリとの協調
コンテナクエリはメディアクエリの代替ではなく、役割分担です:
/* メディアクエリ:ページレベルレイアウトを処理 */
@media (min-width: 1024px) {
.layout {
grid-template-columns: 280px 1fr;
}
}
/* コンテナクエリ:コンポーネントレベルレイアウトを処理 */
@container card (min-width: 400px) {
.card {
flex-direction: row;
}
}
| シナリオ | 使用するもの |
|---|---|
| ページ全体のレイアウト切替 | メディアクエリ |
| コンポーネント内部の適応 | コンテナクエリ |
| グローバルフォントスケーリング | メディアクエリ |
| コンポーネント内テキストのコンテナに応じたスケーリング | コンテナクエリ単位 |
コンテナスタイルクエリ
CSS Container Query Level 3ではスタイルクエリが導入され、コンテナのカスタムプロパティ値に基づいてスタイルを切り替えられます:
.card-container {
container-type: inline-size;
--theme: light;
}
.card-container.dark {
--theme: dark;
}
@container style(--theme: dark) {
.card {
background: #1a1a2e;
color: #e0e0e0;
}
}
@container style(--theme: light) {
.card {
background: #ffffff;
color: #333333;
}
}
パフォーマンス最適化
過度なネストを避ける
/* 非推奨:多層コンテナネスト */
.outer { container: outer / inline-size; }
.middle { container: middle / inline-size; }
.inner { container: inner / inline-size; }
/* 推奨:適応が必要な階層のみコンテナを設定 */
.card-wrapper { container: card / inline-size; }
コンテナサイズ計算
コンテナクエリのサイズ計算は子要素のオーバーフローコンテンツを含みませんが、paddingとborderは含みます。一貫した動作のためにbox-sizing: border-boxを設定してください。
フォールバック戦略
/* 基本スタイル:モバイルファースト */
.card {
flex-direction: column;
}
/* コンテナクエリ拡張 */
@supports (container-type: inline-size) {
.card-container {
container: card / inline-size;
}
@container card (min-width: 400px) {
.card {
flex-direction: row;
}
}
}
/* 非サポート時のメディアクエリフォールバック */
@supports not (container-type: inline-size) {
@media (min-width: 768px) {
.card {
flex-direction: row;
}
}
}
ブラウザ互換性(2026年)
| ブラウザ | コンテナクエリ | コンテナクエリ単位 | スタイルクエリ |
|---|---|---|---|
| Chrome 105+ | ✅ | ✅ | ✅ (117+) |
| Firefox 110+ | ✅ | ✅ | ❌ |
| Safari 16+ | ✅ | ✅ | ✅ (17+) |
| Edge 105+ | ✅ | ✅ | ✅ |
結論:コンテナクエリは主要ブラウザで完全にサポートされており、本番環境で安心して使用できます。スタイルクエリは拡張機能として、@supportsによる段階的採用を推奨します。
ブラウザローカルツールを無料で試す →
#CSS#容器查询#响应式设计#组件化