コンテナクエリでレスポンシブデザインを次のレベルへ!
2024.07.01

コンテナクエリとは?
コンテナクエリは、CSSの機能で、レスポンシブデザインにおける強力なツールです。従来のメディアクエリがビューポート(ブラウザの表示領域)のサイズに基づいてスタイルを適用するのに対し、コンテナクエリは特定の親要素(コンテナ)のサイズに基づいてスタイルを適用します。
コンテナクエリの基本構文
コンテナクエリの基本的な構文は以下のようになります。
@container (min-width: 480px) {
  /* スタイル */
}この例では、親要素(コンテナ)の幅が480px以上の場合に、中のスタイルが適用されます。
コンテナを定義するには、container-type プロパティを使用します。
.container {
  container-type: inline-size;
}このプロパティを使用することで、ブラウザにこの要素がコンテナクエリの対象であることを伝えます。
コンテナクエリの基本的な使い方
コンテナクエリを使用したシンプルな例
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>コンテナクエリの例</title>
  <style>
    .container {
      container-type: inline-size;
      border: 2px solid #333;
      padding: 20px;
      margin: 20px;
      resize: horizontal;
      overflow: auto;
    }
    .card {
      background-color: #f0f0f0;
      padding: 20px;
      margin-bottom: 20px;
    }
    .card img {
      max-width: 100%;
      height: auto;
    }
    @container (min-width: 480px) {
      .card {
        display: flex;
        align-items: center;
      }
      .card img {
        width: 150px;
        margin-right: 20px;
      }
    }
    @container (min-width: 992px) {
      .card {
        font-size: 2em;
      }
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="card">
      <img src="https://via.placeholder.com/150" alt="プレースホルダー画像">
      <div>
        <h2>カードタイトル</h2>
        <p>これはカードの内容です。コンテナのサイズに応じてレイアウトが変化します。</p>
      </div>
    </div>
  </div>
</body>
</html>この例では、カードコンテナの幅が480px以上になると、カードの内容が縦並びから横並びに変わります。


メディアクエリはもういらない?
コンテナクエリが登場したからといって、メディアクエリが不要になるわけではありません。この2つには異なる用途があります。
コンテナクエリ
個々のコンポーネントや要素のレスポンシブな挙動に適しています。
メディアクエリ
ページ全体のレイアウトやグローバルなスタイルの変更に適しています。
この2つを組み合わせることで、より柔軟で効果的なレスポンシブデザインを実現できます。
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>メディアクエリとコンテナクエリの組み合わせ例</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 0;
      background-color: #f0f0f0;
    }
    .main-container {
      max-width: 1200px;
      margin: 0 auto;
      padding: 20px;
    }
    header {
      background-color: #333;
      color: white;
      padding: 20px;
      text-align: center;
    }
    .content-area {
      display: flex;
      flex-direction: column;
    }
    .article-container {
      container-type: inline-size;
      background-color: white;
      padding: 20px;
      margin-bottom: 20px;
    }
    .sidebar {
      background-color: #ddd;
      padding: 20px;
    }
    .card {
      background-color: #f9f9f9;
      border: 1px solid #ddd;
      padding: 15px;
      margin-bottom: 15px;
    }
    /* メディアクエリ: 全体のレイアウト制御 */
    @media (min-width: 768px) {
      .content-area {
        flex-direction: row;
      }
      .article-container {
        flex: 2;
        margin-right: 20px;
      }
      .sidebar {
        flex: 1;
      }
    }
    /* コンテナクエリ: 記事コンテンツの制御 */
    @container (min-width: 400px) {
      .card {
        display: flex;
        align-items: center;
      }
      .card img {
        width: 150px;
        margin-right: 15px;
      }
    }
    @container (min-width: 600px) {
      .card {
        font-size: 1.1em;
      }
    }
  </style>
</head>
<body>
  <header>
    <h1>メディアクエリとコンテナクエリのデモ</h1>
  </header>
  <div class="main-container">
    <div class="content-area">
      <main class="article-container">
        <h2>メイン記事</h2>
        <div class="card">
          <img src="https://via.placeholder.com/150" alt="記事1の画像">
          <div>
            <h3>記事1のタイトル</h3>
            <p>これは記事1の内容です。コンテナのサイズに応じてレイアウトが変化します。</p>
          </div>
        </div>
        <div class="card">
          <img src="https://via.placeholder.com/150" alt="記事2の画像">
          <div>
            <h3>記事2のタイトル</h3>
            <p>これは記事2の内容です。画面幅だけでなく、コンテナのサイズも考慮されます。</p>
          </div>
        </div>
      </main>
      <aside class="sidebar">
        <h2>サイドバー</h2>
        <p>ここはサイドバーの内容です。画面幅に応じて配置が変わります。</p>
      </aside>
    </div>
  </div>
</body>
</html>まとめ
コンテナクエリは、レスポンシブデザインの新しい強力なツールです。
これまでの主要なポイントをまとめます。
コンテナクエリの特徴
- 親要素(コンテナ)のサイズに基づいてスタイルを適用
- より細かな制御が可能になり、コンポーネントレベルでのレスポンシブデザインを実現
基本的な使い方
- container-typeプロパティでコンテナを定義
- @containerルールを使用してスタイルを指定
メディアクエリとの違い
- コンテナクエリ:個々のコンポーネントや要素のレスポンシブな挙動に適している
- メディアクエリ:ページ全体のレイアウトやグローバルなスタイルの変更に適している
組み合わせの重要性
- コンテナクエリとメディアクエリを組み合わせることで、より柔軟で効果的なレスポンシブデザインが可能
メリット
- コンポーネントの再利用性が向上
- デザインの一貫性を保ちながら、異なるコンテキストに適応可能
コンテナクエリを活用することで、よりきめ細かなレスポンシブデザインが実現できます。ただし、従来のメディアクエリも依然として重要な役割を果たしています。両者を適切に組み合わせることで、モダンでユーザーフレンドリーなウェブデザインを作成できるでしょう。
