Featured image of post コンテナクエリ (Container Queries) を使ったモジュール型レスポンシブ設計 Featured image of post コンテナクエリ (Container Queries) を使ったモジュール型レスポンシブ設計

コンテナクエリ (Container Queries) を使ったモジュール型レスポンシブ設計

CSSコンテナクエリ(Container Queries)を使ったモジュール型レスポンシブ設計を徹底解説。親コンテナの幅に基づいてレイアウトを自動調整する手法と、従来のメディアクエリとの設計思想の違いを、ReactやVueのコンポーネント指向開発の視点から解説します。

はじめに

レスポンシブWebデザインにおいて、長年使われてきた定番の手法が メディアクエリ(Media Queries: @media です。

メディアクエリは、ブラウザの「画面幅(ビューポート)」を基準にしてスタイルを切り替えます。しかし、コンポーネント指向の開発(React, Vue, Web Componentsなど)が主流となった現代において、画面幅依存のレスポンシブ設計には大きな限界がありました。

例えば、「同じカードコンポーネントを、広いメインカラムと狭いサイドバーの両方で再利用したい」という場合、メディアクエリでは配置先の幅を検知できないため、CSSが崩れてしまいます。

この課題を根本から解決するのが、CSSの標準機能である コンテナクエリ(Container Queries: @container です。本記事では、コンテナクエリの基本と実践的なマークアップ手法を解説します。


1. メディアクエリとコンテナクエリの根本的な違い

メディアクエリ(画面幅基準)

ブラウザのウィンドウ全体の幅が変わると、ページ上のすべての要素のスタイルが一斉に変化します。

  • 課題: コンポーネントが「ページのどこに配置されているか」に関係なく、画面幅だけでスタイルが決まるため、モジュールとしての独立性が保てません。

コンテナクエリ(親要素の幅基準)

コンポーネントが配置されている 「すぐ親のコンテナ要素の幅」 に応じて、コンポーネント自身のスタイルを個別に変化させます。

  • メリット: メインカラム(広いスペース)に置かれたときはグリッド(横並び)で表示され、サイドバー(狭いスペース)に置かれたときはリスト(縦並び)で表示されるような、真に自己完結したレスポンシブコンポーネントが作れます。

2. コンテナクエリの基本実装

コンテナクエリを使用するためには、CSSで以下の2つの設定を行います。

  1. 親要素を「コンテナ(監視対象)」として登録する (container-type)。
  2. 子要素に対して、コンテナ幅を基準にしたスタイルを適用する (@container)。

HTML構造

<!-- 親コンテナ -->
<div class="card-wrapper">
  <!-- 自律的なカードコンポーネント -->
  <div class="my-card">
    <img src="thumb.jpg" alt="画像" class="card-img" />
    <div class="card-content">
      <h3>記事のタイトル</h3>
      <p>記事の短い要約テキスト...</p>
    </div>
  </div>
</div>

CSSの実装

/* 1. 親要素をコンテナとして定義 */
.card-wrapper {
  /* inline-size は「横幅のみ」を監視対象にすることを意味します */
  container-type: inline-size;
  /* オプション: コンテナに名前を付けて、特定のコンテナだけを監視することも可能 */
  container-name: card-container;
}

/* 通常の(狭い幅のときの)カードスタイル */
.my-card {
  display: flex;
  flex-direction: column; /* 縦並び */
  gap: 15px;
}

/* 2. コンテナ幅が 400px 以上になった場合のスタイル指定 */
@container (min-width: 400px) {
  .my-card {
    flex-direction: row; /* 横並びに変更 */
    align-items: center;
  }
  .card-img {
    width: 150px;
    height: 100px;
  }
}

この設定により、.card-wrapper 自体の幅が 400px を超えると、内部のカードが自動的に「横並びレイアウト」に切り替わります。画面全体の幅がどれほど広くても、親要素の幅が狭ければ、縦並びの状態で綺麗に表示され続けます。


3. 新しいコンテナクエリ専用の単位(cqw, cqh)

コンテナクエリの導入に伴い、コンテナのサイズに基づいた新しいCSS単位(Container Query Units)も利用できるようになりました。

  • cqw: コンテナの幅の 1%
  • cqh: コンテナの高さの 1%
  • cqmin: cqw と cqh のうち、小さい方の 1%
  • cqmax: cqw と cqh のうち、大きい方の 1%

例えば、コンテナの幅に応じてフォントサイズを動的に調整したい場合に非常に役立ちます。

.card-content h3 {
  /* コンテナの幅の 5% の大きさにフォントサイズを自動スケールする */
  font-size: clamp(1rem, 5cqw, 2rem);
}

まとめとブラウザ対応状況

CSS コンテナクエリは、現在 Chrome、Safari、Edge、Firefox を含むすべての主要なモダンブラウザでフルサポートされています。ポリフィル(Polyfill)も提供されているため、少し古いブラウザがターゲットに含まれる場合でも導入が可能です。

コンテナクエリを採用することで、

  1. 画面幅(メディアクエリ)の複雑な条件分岐から解放される
  2. コンポーネントをどこにでも配置できる再利用性が手に入る
  3. 要素のサイズに応じた最適なタイポグラフィ(cqw)を簡単に設定できる

これからのCSS設計・モジュール開発において標準となるこのコンテナクエリを、ぜひ実際のプロジェクトに取り入れてみてください。