Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【CSS Modules】@containerアットルールの使い方

@containerアットルールの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

@containerオブジェクトは、コンテナクエリを定義するためのルールを表すオブジェクトです。このルールは、従来のメディアクエリがブラウザのビューポート全体に基づいてスタイルを適用するのとは異なり、特定の親要素(「コンテナ」と呼ばれます)のサイズやスタイルといった状態に基づいて、そのコンテナ内部の子要素のスタイルを調整できるようにします。

これにより、WebページのUIコンポーネントは、配置される場所(コンテナ)の利用可能なスペースや特性に応じて、自動的に自身のレイアウトや表示を最適化することが可能になります。例えば、サイドバーに配置されたカードコンポーネントと、メインコンテンツ領域に配置された同じカードコンポーネントが、それぞれ異なる幅のコンテナ内で最適な表示を行うように、独立してスタイルを変化させることができます。

@containerを使用するには、まず、スタイルを適用したい子要素の親要素に対し、container-typeプロパティを設定することで、その要素をコンテナとして定義する必要があります。その後、@container (条件) { ... }という構文を用いて、定義したコンテナの特定の条件(例えば、コンテナの最小幅が400px以上であるなど)が満たされた場合に適用するCSSスタイルを記述します。

この機能は、特にコンポーネント指向のWeb開発において極めて重要です。再利用可能なUIコンポーネントを設計する際に、コンポーネントが自身の内部で完結してレスポンシブな振る舞いを定義できるようになるため、より柔軟で予測しやすいWebデザインを実現します。個々のコンポーネントが自身のコンテナの状況を判断し、独立してスタイルを変化させることができるため、大規模なアプリケーション開発における保守性と拡張性が大幅に向上します。

公式リファレンス: @container

構文(syntax)

1@container (min-width: 768px) {
2  .card {
3    display: grid;
4    grid-template-columns: 1fr 1fr;
5    gap: 1rem;
6  }
7}

引数(parameters)

引数なし

引数はありません

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

CSS container使い方:幅でスタイルを切り替える

1/*
2 * システムエンジニアを目指す初心者向けのCSS @container at-ruleのサンプルコード
3 *
4 * このコードは、親要素の幅に基づいて子要素のスタイルを動的に調整する方法を示します。
5 * `@container`は、特定のコンテナ要素(親要素)のサイズに基づいてスタイルを適用する際に使用されます。
6 * 従来のメディアクエリがビューポート全体を参照するのに対し、`@container`は指定された親要素のみを参照します。
7 */
8
9/*
10 * 1. コンテナとして機能する要素を定義します。
11 * `container-type` プロパティを使って、この要素をコンテナクエリのコンテナとしてマークします。
12 * `inline-size` は、要素のインライン方向(通常は幅)のサイズ変更を監視することを示します。
13 */
14.card-container {
15  /*
16   * この要素をコンテナクエリの対象コンテナとして定義します。
17   * inline-size を指定すると、この要素の幅に基づいて内部のスタイルを変更できるようになります。
18   */
19  container-type: inline-size;
20
21  /* サンプルを分かりやすくするためのスタイル */
22  min-width: 250px; /* 最小幅 */
23  max-width: 700px; /* 最大幅 */
24  border: 1px solid #ccc;
25  border-radius: 8px;
26  padding: 10px;
27  margin: 20px auto; /* ページ中央に配置 */
28  background-color: #f0f0f0;
29  overflow: auto; /* resize プロパティと合わせて使用 */
30  resize: horizontal; /* ユーザーがこの要素の幅をドラッグで変更できるようにします (デモンストレーション用) */
31}
32
33/*
34 * 2. コンテナ内に配置される子要素(カードコンポーネント)の基本的なスタイルを定義します。
35 */
36.card {
37  display: flex; /* Flexboxを使って内部要素を配置 */
38  flex-direction: column; /* デフォルトでは縦並び */
39  gap: 10px; /* 要素間のスペース */
40  background-color: #fff;
41  border: 1px solid #eee;
42  border-radius: 5px;
43  padding: 15px;
44  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
45}
46
47.card-image {
48  max-width: 100%;
49  height: auto; /* アスペクト比を維持 */
50  border-radius: 4px;
51}
52
53.card-content {
54  /* カードのテキストコンテンツ部分 */
55}
56
57.card-title {
58  font-size: 1.2em;
59  color: #333;
60  margin-bottom: 5px;
61}
62
63.card-body {
64  font-size: 0.9em;
65  color: #555;
66  line-height: 1.5;
67}
68
69/*
70 * 3. @container ルールを使って、`.card-container` の幅に基づいて子要素のスタイルを変更します。
71 * この例では、コンテナの幅が 400px 以上になった場合にカードのレイアウトを横並びに変更します。
72 */
73@container (min-width: 400px) {
74  /*
75   * `.card-container` の幅が 400px 以上になった場合、
76   * `.card` のレイアウトを横並びに変更し、画像とテキストコンテンツを配置します。
77   */
78  .card {
79    flex-direction: row; /* 横並びに変更 */
80    align-items: center; /* 垂直方向の中央揃え */
81    gap: 20px; /* 画像とテキスト間のスペース */
82  }
83
84  .card-image {
85    width: 150px; /* 横並び時の画像の固定幅 */
86    flex-shrink: 0; /* 画像が縮まないように */
87  }
88
89  .card-content {
90    flex-grow: 1; /* テキストコンテンツが残りのスペースを埋めるように */
91  }
92
93  .card-title {
94    font-size: 1.4em; /* 横並び時にタイトルを少し大きく */
95  }
96}

CSSの@containerは、特定の親要素(コンテナ)のサイズに基づいて、その中の子要素のスタイルを動的に変更するためのアットルールです。従来のメディアクエリがブラウザ全体の表示領域(ビューポート)のサイズを参照するのに対し、@containerは指定した個別のコンテナのサイズだけを参照するため、コンポーネント単位でより柔軟なレスポンシブデザインを実現できます。

このサンプルコードでは、まず.card-container要素にcontainer-type: inline-size;を設定しています。これは、この要素をコンテナクエリの対象となるコンテナとして定義し、そのインライン方向のサイズ(通常は幅)の変更を監視することを示します。

次に、@container (min-width: 400px)ルールを記述し、.card-containerの幅が400px以上になった場合に適用されるスタイルを定義しています。コンテナの幅が400px未満の場合、内部の.card要素は縦並びのレイアウトです。しかし、コンテナの幅が400px以上になると、この@containerブロック内のスタイルが適用され、.card要素はflex-direction: row;によって画像とテキストが横並びのレイアウトに変化します。同時に、画像やタイトルのサイズも調整され、コンテナのスペースに応じて最適な表示に変わります。

@containerは引数を取らず、特定の値を戻り値として返しません。その役割は、指定されたコンテナのサイズ条件を満たしたときに、そのブロック内に記述されたCSSルールを適用することです。これにより、コンポーネントが配置される場所のスペースに応じて、その見た目を自動的に調整する強力な機能を提供します。

@containerルールを適用するには、まず親要素にcontainer-typeプロパティ(例: container-type: inline-size;)を設定し、その要素をコンテナとして明示的に定義する必要があります。これを忘れるとスタイルが適用されませんのでご注意ください。inline-sizeは主に要素の幅を、block-sizeは高さを監視しますので、どのサイズに基づいてスタイルを変更したいかに応じて適切に指定してください。

このルールは、ブラウザ全体のビューポートを参照する従来のメディアクエリとは異なり、「特定の親要素のサイズ」に基づいてスタイルを変更します。この違いを理解し、適切な場面で使い分けることが重要です。@containerは比較的新しいCSS機能ですので、本番環境で使用する際は、ターゲットとするブラウザがこの機能をサポートしているか、事前に必ず確認するようにしましょう。

コンテナクエリで要素スタイルを制御する

1/*
2 * このCSSは、特定の要素(コンテナ)のサイズに基づいて、
3 * その内部にある要素のスタイルを変更する「コンテナクエリ」の基本的な使用例です。
4 *
5 * 1. コンテナを定義する要素(親要素)
6 *    - `container-type: inline-size`: このプロパティは、コンテナの「幅」に基づいてクエリを実行することを指定します。
7 *      これにより、コンテナの水平方向のサイズ変更に応じてスタイルを適用できます。
8 *    - `container-name: my-component`: このコンテナに一意の名前を付け、
9 *      後述の `@container` ルールでこのコンテナを識別できるようにします。
10 */
11.component-container {
12  container-type: inline-size;
13  container-name: my-component;
14  width: 100%;
15  max-width: 768px; /* コンテナの最大幅を設定し、動作を確認しやすくします */
16  margin: 20px auto;
17  padding: 15px;
18  border: 1px solid #e0e0e0;
19  background-color: #f9f9f9;
20  display: flex;
21  flex-wrap: wrap; /* 子要素が複数行になる可能性を考慮 */
22  gap: 10px;
23}
24
25/*
26 * コンテナ内部のアイテム(子要素)
27 * これらの要素は、親である `.component-container` の幅に基づいてスタイルが変化します。
28 */
29.component-item {
30  flex: 1 1 150px; /* 最小幅150pxで、可能な限り広がるように設定 */
31  background-color: #ffffff;
32  padding: 15px;
33  border: 1px solid #dcdcdc;
34  border-radius: 6px;
35  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
36  text-align: center;
37  font-size: 0.9em;
38  color: #333;
39}
40
41.component-item h3 {
42  margin-top: 0;
43  margin-bottom: 8px;
44  font-size: 1.1em;
45  color: #0056b3;
46}
47
48/*
49 * 2. `@container` ルールでコンテナのサイズに応じたスタイルを適用
50 *    - `@container my-component (min-width: 300px)`: これは、
51 *      名前が `my-component` のコンテナの「幅」が300px以上になった場合にのみ、
52 *      このブロック内のCSSスタイルを適用するというルールです。
53 *    - 親要素のサイズに応じて、子要素のレイアウトや見た目を動的に調整できます。
54 */
55@container my-component (min-width: 300px) {
56  .component-item {
57    text-align: left; /* コンテナ幅が300px以上の場合、アイテムのテキストを左寄せに */
58    padding: 20px;
59    font-size: 1em; /* フォントサイズを少し大きくする */
60  }
61
62  .component-item h3 {
63    font-size: 1.25em; /* 見出しを大きくする */
64  }
65}
66
67/*
68 * さらに広いコンテナ幅でのスタイル変更
69 */
70@container my-component (min-width: 600px) {
71  .component-container {
72    gap: 20px; /* コンテナ幅が600px以上の場合、アイテム間の間隔を広げる */
73  }
74
75  .component-item {
76    flex: 1 1 250px; /* アイテムのベース幅を広くする */
77    background-color: #eaf6ff; /* 背景色を変更する */
78  }
79}

@containerは、特定の要素(コンテナ)のサイズに基づいて、その内部にある要素のスタイルを変更するCSSの新しい機能「コンテナクエリ」を定義するアットルールです。これまでのメディアクエリがビューポート(画面全体)のサイズに基づいてスタイルを適用していたのに対し、@containerは個々のコンポーネント(部品)のサイズに応じてスタイルを調整できるため、より柔軟で再利用性の高いコンポーネント設計が可能になります。

このルールを使用するには、まず親となる要素にcontainer-typeプロパティでクエリの基準(例: inline-sizeで幅)を指定し、container-nameプロパティでコンテナに一意の名前を付けます。今回のサンプルコードでは、.component-containercontainer-type: inline-size;container-name: my-component;で定義されており、その幅に基づいて子要素のスタイルが変化するコンテナとして機能します。

そして、@container <コンテナ名> (<条件>)という形式で、そのコンテナのサイズ条件が満たされた場合に適用されるスタイルを記述します。サンプルコードでは、@container my-component (min-width: 300px)のように、my-componentという名前のコンテナの幅が300px以上になった場合に、その内部の.component-itemの文字寄せやフォントサイズが変更される例を示しています。さらに、min-width: 600pxの条件では、アイテム間の間隔や背景色も変化します。

@containerは引数や戻り値を持たず、条件式に基づいてCSSブロック全体を適用するかしないかを制御する仕組みです。これにより、親コンポーネントの利用可能なスペースに応じて、子コンポーネントの表示を最適化し、レスポンシブなデザインをよりきめ細かく実現できます。

このサンプルコードでは、まず親要素にcontainer-typecontainer-nameを設定して、対象となるコンテナを定義することが非常に重要です。特にcontainer-type: inline-sizeは、コンテナの「幅」に基づいてスタイルを適用するよう指定しています。@containerルールは、この定義された親要素のサイズを参照し、その条件を満たした場合にのみ内部の子要素のスタイルを変更します。ビューポート全体ではなく、特定のコンテナのサイズ変化に応じたきめ細やかなレスポンシブデザインが可能になります。container-nameは、複数のコンテナがある場合に区別するために使用すると便利です。

関連コンテンツ

関連IT用語