コンテナクエリ(@container)の使い方|置いた場所の幅に合わせて変わる部品を、コピペ4種類と使いどころで

コンテナクエリで置き場所に合わせる。本文とサイドバーで並べ方が変わるカードとボタンの見本とコード

同じカードを、トップページの広い場所と、サイドバーの狭い場所の両方に置きたい。ところが、画面の幅で見た目を切りかえる @media では、同じ画面の中にある「広い場所のカード」と「狭い場所のカード」を別々に切りかえられません。そこで使うのが、置いた場所の幅を調べるコンテナクエリ(@container)です。

使いどころは「同じ部品を、幅のちがう場所に置き回すとき」です。本文とサイドバー、1列と3列の一覧など、置き場所によって使える幅が変わる部品に使います。ページ全体の組み方(ヘッダーのメニューを畳むなど)は、これまでどおり画面の幅を見る @media で書きます。

この記事の要点

  • コンテナクエリ(@container)は、画面の幅ではなく「部品を置いた箱の幅」で見た目を切りかえる書き方。外側の箱に container-type: inline-size を付けて使う
  • 使いどころは、カードやボタン、お知らせの一覧など、同じ部品を本文・サイドバー・一覧の列など、幅のちがう場所に置き回すとき
  • 調べられるのは外側の箱の幅で、箱そのものの見た目は変えられない。幅が決まっていない箱に付けると、箱がつぶれることがある
トミー

連載「WEBの技術」の40回目です。
clamp() の回、グリッドで並べる回と、「幅に合わせて変わる」話を何度かしてきました。今回は、画面ではなく「置いた場所」の幅に合わせる方法です。

完成見本:置き場所の幅で変わる部品4種類

下の4つは、点線の箱の幅を、ページを開いた時点から自動で 520px と 260px の間で動かしています。画面の幅は変わっていないのに、箱が狭くなると、カードは縦並びに、見出しは小さく、ボタンは縦積みに、お知らせは2行に変わります。切りかえはCSSだけです。

※ 見本は読み上げソフトでは読まれないようにしています。スマホでは見本全体を縮めて表示しています。動きを減らす設定にしている場合は、箱の幅は動きません。

コピペ用のコード

HTMLは使いたい場所に、CSSはサイトのCSSファイルや、WordPressならテーマの「追加CSS」などに入れます。クラス名の頭の kd- は、サイトのほかのデザインと名前がぶつからないようにするための目印です。1・2・4の最初にある .kd-cq の指定は同じものなので、まとめて使うときは1つにしてかまいません。

1. 幅が広いときだけ、横に並べる

同じカードを、広い場所では「画像+文字」の横並びに、狭い場所では画像が上の縦並びにする形です。.kd-cq に container-type: inline-size を付けると、その箱の横幅を調べられるようになります。@container (width >= 400px) は「外側の箱の幅が400px以上のとき」という意味です。画面の幅ではなく、カードを置いた場所の幅で切りかわります。

HTML
<div class="kd-cq">
  <div class="kd-ccard">
    <img src="photo.jpg" alt="" width="1200" height="800">
    <div>
      <p class="kd-ccard-title">海の見える家の施工事例</p>
      <p class="kd-ccard-text">置いた場所の幅に合わせて、並べ方が変わります。</p>
    </div>
  </div>
</div>
CSS
/* 外側の箱を「幅を調べられる箱(コンテナ)」にする */
.kd-cq {
  container-type: inline-size;
}
.kd-ccard {
  display: grid;
  gap: 12px;
  padding: 14px;
  border: 1px solid #D8E6F0;
  border-radius: 12px;
  background: #fff;
}
.kd-ccard img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 8px;
}
.kd-ccard-title {
  margin: 0 0 4px;
  font-size: 16px;
  font-weight: 700;
  line-height: 1.5;
  color: #10283A;
}
.kd-ccard-text {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  color: #5A6E7E;
}
/* 外側の箱の幅が400px以上のときだけ、画像と文字を横に並べる */
@container (width >= 400px) {
  .kd-ccard {
    grid-template-columns: 160px minmax(0, 1fr);
    align-items: center;
  }
  .kd-ccard img {
    aspect-ratio: 1;
  }
}

2. 箱の幅に合わせて、文字の大きさを変える

見出しの文字の大きさと余白を、外側の箱の幅に合わせて変える形です。cqi は「外側の箱の横幅の1%」を表す単位で、7cqi なら幅の7%です。連載で以前紹介した clamp() と組み合わせ、18pxより小さく、34pxより大きくならないようにしています。

HTML
<div class="kd-cq">
  <div class="kd-chead">
    <p class="kd-chead-en">CAMPAIGN</p>
    <p class="kd-chead-title">秋の見学会を開きます</p>
  </div>
</div>
CSS
/* 外側の箱を「幅を調べられる箱(コンテナ)」にする */
.kd-cq {
  container-type: inline-size;
}
.kd-chead {
  padding: clamp(16px, 6cqi, 36px);
  border-radius: 14px;
  background: #0369A1;
  color: #fff;
}
.kd-chead-en {
  margin: 0 0 4px;
  font-size: clamp(11px, 2.6cqi, 14px);
  font-weight: 700;
  letter-spacing: .14em;
}
/* 文字の大きさを、外側の箱の幅の7%に(18px〜34pxの間で) */
.kd-chead-title {
  margin: 0;
  font-size: clamp(18px, 7cqi, 34px);
  font-weight: 800;
  line-height: 1.35;
}

3. 狭い場所では、ボタンを縦に積む

ボタン2つを、広い場所では横に、狭い場所では縦に積む形です。ここでは箱に actions という名前を付けています。container: actions / inline-size は「名前は actions、横幅を調べる箱」という書き方をまとめたものです。@container actions (…) と名前を書くと、間にほかのコンテナがあっても、actions の箱の幅だけを見ます。

HTML
<div class="kd-cact-wrap">
  <div class="kd-cact">
    <a class="kd-cact-btn is-main" href="#">見学を申し込む</a>
    <a class="kd-cact-btn is-sub" href="#">資料を見る</a>
  </div>
</div>
CSS
/* 名前(actions)を付けて、どの箱の幅を見るかをはっきりさせる */
.kd-cact-wrap {
  container: actions / inline-size;
}
.kd-cact {
  display: flex;
  gap: 10px;
}
.kd-cact-btn {
  flex: 1;
  display: block;
  padding: 12px 16px;
  border: 2px solid #0369A1;
  border-radius: 999px;
  font-weight: 700;
  text-align: center;
  text-decoration: none;
}
.kd-cact-btn.is-main {
  background: #0369A1;
  color: #fff;
}
.kd-cact-btn.is-sub {
  background: #fff;
  color: #0369A1;
}
.kd-cact-btn:focus-visible {
  outline: 3px solid #0284C7;
  outline-offset: 3px;
}
/* actions の箱が360pxより狭いときは、ボタンを縦に積む */
@container actions (width < 360px) {
  .kd-cact {
    flex-direction: column;
  }
}

4. お知らせの1行を、幅で組みかえる

日付・カテゴリー・題名を、広い場所では1行に、狭い場所では「日付とカテゴリー」と「題名」の2行に組みかえる形です。トップページの広い場所と、サイドバーの狭い場所に同じ一覧を置いても、どちらでも読みやすくなります。

HTML
<div class="kd-cq">
  <ul class="kd-cnews">
    <li>
      <time datetime="2026-11-04">2026.11.04</time>
      <span class="kd-cnews-cat">お知らせ</span>
      <a class="kd-cnews-title" href="#">年末年始の営業日のご案内</a>
    </li>
    <li>
      <time datetime="2026-10-28">2026.10.28</time>
      <span class="kd-cnews-cat">施工事例</span>
      <a class="kd-cnews-title" href="#">海の見える家の施工事例を公開しました</a>
    </li>
    <li>
      <time datetime="2026-10-15">2026.10.15</time>
      <span class="kd-cnews-cat">イベント</span>
      <a class="kd-cnews-title" href="#">11月の見学会の申し込みを始めました</a>
    </li>
  </ul>
</div>
CSS
/* 外側の箱を「幅を調べられる箱(コンテナ)」にする */
.kd-cq {
  container-type: inline-size;
}
.kd-cnews {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid #D8E6F0;
}
.kd-cnews li {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  align-items: center;
  gap: 6px 14px;
  padding: 12px 4px;
  border-bottom: 1px solid #D8E6F0;
}
.kd-cnews time {
  font-size: 14px;
  color: #5A6E7E;
  font-variant-numeric: tabular-nums;
}
.kd-cnews-cat {
  justify-self: start;
  padding: 2px 10px;
  border-radius: 999px;
  background: #E0F2FE;
  color: #0C4A6E;
  font-size: 12px;
  font-weight: 700;
}
.kd-cnews-title {
  font-size: 15px;
  color: #10283A;
}
/* 狭いときは、日付とカテゴリーを上の行に、題名を下の行にする */
@container (width < 440px) {
  .kd-cnews li {
    grid-template-columns: auto minmax(0, 1fr);
  }
  .kd-cnews-title {
    grid-column: 1 / -1;
  }
}

仕組み:「調べる箱」と「変える部品」を分ける

まず、外側の箱を「コンテナ」にする

コンテナクエリを使うには、幅を調べたい外側の箱に container-type: inline-size を付けます。これで、その箱は「横幅を調べられる箱(コンテナ)」になります。inline-size は、横書きのページでは「横幅」のことです。

付けられる値は3つあります。MDNによると、inline-size は横幅だけ、size は横幅と高さの両方を調べる箱にします。normal はもとの状態で、幅を調べる箱にはなりません。ふだんは inline-size で足ります。

@container の中に、変えたい部品の指定を書く

@container (width >= 400px) { … } と書くと、「いちばん近いコンテナの幅が400px以上のとき」だけ、中の指定が当たります。書き方は @media とほとんど同じで、見ている幅が「画面」から「外側の箱」に変わったと考えると分かりやすくなります。

書き方見ている幅向いているもの
@media (width >= 768px)画面(ブラウザの表示部分)の幅ページ全体の組み方、ヘッダー、メニュー
@container (width >= 400px)いちばん近いコンテナの幅カード、ボタンの並び、一覧の1行
@container actions (width < 360px)actions という名前のコンテナの幅入れ子になった部品で、見る箱を決めたいとき

箱そのものは変えられない

コンテナクエリで見た目を変えられるのは、コンテナの中にある部品です。コンテナそのものの見た目は、自分の幅を見て変えることはできません。そのため、見本ではどれも「外側の .kd-cq」と「中の部品」を分けて書いています。HTMLが1つ増えますが、ここがいちばんつまずきやすいところです。

cqi は「コンテナの幅の1%」

2で使っている cqi は、コンテナの横幅の1%を表す単位です。7cqi なら、幅300pxの箱では21px、幅400pxの箱では28pxになります。画面の幅の1%を表す vw のコンテナ版です。MDNによると、まわりにコンテナがないときは、画面の大きさを基準にした単位に置きかわります。

幅が決まっていない箱に付けると、つぶれる

MDNによると、container-type: inline-size を付けた箱の横幅は、中身を見ずに決まります。ふつうのブロックの箱は親の幅いっぱいに広がるので問題ありませんが、横並び(flex)の中で幅を決めていない箱や、float した箱などに付けると、幅が0のようにつぶれることがあります。コンテナにするのは、幅が外から決まる箱だけにします。

数値を変えるとどうなるか

置き場所で、同じカードがこう変わる

上は、1のカードを、幅300pxのサイドバーと、幅520pxの本文に置いたところです。HTMLもCSSもまったく同じで、画面の幅も同じです。@media だけで書くと、どちらか一方に合わせるしかありませんでした。

cqi の数字を変える

2の見出しを、同じ幅300pxの箱で、5cqi・7cqi・10cqi にしたところです。5cqiは15pxになりますが、clamp() の最小値18pxで止まります。数字を大きくすると、狭い箱では1行に入る文字が減ります。見出しの文字数が多いサイトでは、5〜7cqiくらいがおさまりやすい値です。

変えるところ指定今回の値目安
横並びにする幅(1)@container (width >= …)400px画像160px+文字1行15字ほど入る幅
見出しの大きさ(2)clamp(最小, ○cqi, 最大)18px・7cqi・34px最小は本文より少し大きく
ボタンを積む幅(3)@container actions (width < …)360pxボタンの文字が1行におさまらなくなる手前
2行にする幅(4)@container (width < …)440px題名が20字ほど入らなくなる幅

スマホと、見る人への配慮

文字を大きくしたときも、崩れない

ブラウザの設定で文字を大きくすると、同じ幅の箱に入る文字が減ります。WCAG(ウェブのアクセシビリティの国際的な基準)2.2の達成基準1.4.4では、文字を200%まで大きくしても内容が失われないこととされています。また達成基準1.4.10では、幅320px相当でも横にスクロールせずに読めることとされています。1や4のように、狭くなったら縦に並べる形にしておくと、文字が大きくなっても横にはみ出しにくくなります。

cqi だけで文字の大きさを決めない

font-size: 7cqi のように cqi だけで決めると、箱がとても狭いときに文字が小さくなりすぎます。2では clamp() で最小18pxにしています。本文の文字には使わず、見出しや帯の文字など、大きめの文字に使うのが安心です。

並べ方を変えても、読む順番は変えない

4は、狭いときに題名を下の行に回していますが、HTMLの順番(日付→カテゴリー→題名)は変えていません。CSSの order などで見た目の順番だけを入れかえると、キーボードで移動する順番や読み上げの順番とずれてしまいます。並べ方は変えても、順番は変えないのが基本です。

ボタンの文字と背景の差

3のボタンは、濃い青 #0369A1 と白の組み合わせで、文字と背景の差は5.9:1です。KAKERUブルー #0EA5E9 を背景にすると白い文字との差が足りないので、ボタンには濃い青を使っています。

トミー

コンテナクエリを知ると、@media を全部 @container に書きかえたくなります。
でも、ページ全体の組み方は画面の幅で決めるもの。部品は置き場所で、ページは画面で。この分け方がいちばん迷わないと思います。

AIに頼むなら

同じような部品は、Claudeなどの生成AIに頼んでもすぐ作れます。そのときは、「どこに置く部品か」と「何pxで切りかえたいか」まで伝えると、画面の幅で切りかえる @media だけのコードになりにくくなります。

ブログのカードを、本文(幅700px)とサイドバー(幅300px)の両方に置きたい。
@media ではなくコンテナクエリで、置いた箱の幅が400px以上なら画像と文字を横並び、狭いときは縦並びにして。
カードを包む外側の箱に container-type を付けて、HTMLの順番は変えないで。

AIが出したコードは、そのまま使う前に、次の3つを確かめます。

  • container-type を、変えたい部品そのものに付けていないか。部品そのものに付けると、その部品の見た目は切りかわりません。外側の箱に付いているかを見ます
  • 横並びの中など、幅が決まっていない箱に付けていないか。箱がつぶれて、中身が見えなくなることがあります
  • スマホ幅(320〜390px)と、文字を大きくした状態で崩れないか。狭い箱でボタンや題名がはみ出していないかを見ます

KAKERUならこう使う/使わない

最後に、作り手としての判断です。

使う場面

  • 本文とサイドバーの両方に出す、記事やお知らせのカード。WordPressのウィジェットやブロックで、同じ部品をどこに置いても崩れないようにできます
  • 1列・2列・3列と、並べる数が変わる一覧の中身。グリッドで並べる回のように列の数が変わっても、カードの中身はカードの幅に合わせて組みかわります
  • 申し込みボタンなど、置く場所が決まっていない部品。記事の途中にも、狭い枠の中にも置けるようにしておくと、更新する人が置き場所を気にしなくてすみます

使わない場面

  • ヘッダーのメニューを畳むなど、ページ全体の組み方。これは画面の幅で決めるものなので、@media で書きます
  • どこに置いても同じ見た目でよい部品。コンテナにすると箱の幅の決まり方が変わるので、必要のないところには付けません
  • 1つしか置かない大きな部品。トップページのいちばん上の大きな画像のように、置き場所が1か所なら、@media で十分です
トミー

KAKERUなら、WordPressで「この部品、サイドバーにも置きたい」と言われたときにコンテナクエリを使います。
置き場所ごとに別の部品を作らなくていいので、直すところが1か所ですみます。

まとめ

  • コンテナクエリ(@container)は、画面ではなく「部品を置いた箱の幅」で見た目を切りかえる書き方
  • 外側の箱に container-type: inline-size を付け、@container の中に中の部品の指定を書く。箱そのものは変えられない
  • cqi はコンテナの幅の1%。文字の大きさに使うときは clamp() で最小と最大を決める
  • 幅が決まっていない箱に付けると、つぶれることがある
  • 部品は置き場所(@container)で、ページ全体は画面(@media)で切りかえる

まずは1のカードをコピーして、本文とサイドバーの両方に置いてみてください。

参考にした資料

いずれも2026年11月4日に確認しました。ブラウザの対応状況は変わることがあります。最新の情報は各ページでご確認ください。

ふだんの制作の話や、作ったものの裏側は Instagram と X でも出しています。

関連記事

画面の幅で文字の大きさを変えるCSS clamp() の式の作り方と、使う・使わないの判断
カードを並べるCSS。グリッドで自動で折り返す、auto-fillとauto-fitの違いと使う・使わないの判断
:has()でできること。画像があるカード・チェックした項目・数で並びが変わるタグの見本とコード
ヘッダーを上に固定するCSS。position: stickyが止まらない原因と、使う・使わないの判断
コンテナクエリで置き場所に合わせる。本文とサイドバーで並べ方が変わるカードとボタンの見本とコード

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

CAPTCHA


ABOUTこの記事をかいた人

25歳からWEBの世界に携わり、WEBデザインから始めて、今はWEBシステムまで一貫して制作しています。問題点を洗い出し、改善を提案する中で、WEB・グラフィック・動画・システムを縦断して提案するのが得意です。