※本記事にはPRを含む場合があります。

こんにちは。『脱会社員』脱サラを応援し続けるブログ、運営者の『なかびー』です。

CSS Gridは、要素を行と列の関係で配置する仕組みです。カード一覧を揃える、本文と補足欄を並べる、画面幅に合わせて構成を切り替えるといった場面で役立ちます。ただ、指定を丸ごとコピーするだけでは、列がはみ出す、意図しない行ができる、見た目と操作順が食い違うといった問題を直しにくくなります。

この記事では、親と子の基本から、列幅、線番号、名前付きエリア、画面幅への対応、崩れの検証へ進みます。HTMLの要素とclass、CSSのセレクターを少し学んだ方向けです。作例は架空の学習カード一覧で、外部通信やサービス登録は不要です。練習用のHTMLファイルを作り、指定を一つずつ変えて動きを確認してください。

2026年10月3日にMDNのGrid関連資料を確認しました。コードは本記事用の学習例で、本番サイトのCSSやすべてのブラウザーでの表示を保証するものではありません。図版は説明用の生成イメージで、コードの実行結果のスクリーンショットではありません。実際の表示は文章、画面幅、ほかのCSSを含めて確認します。

CSS Gridの基本|親と子・行と列・トラックを理解する

CSS Gridの基本|親と子・行と列・トラックを理解する(説明用生成イメージ)

display:gridは並べる範囲の親へ指定する

Gridを使うときは、配置する範囲となる親にdisplay:gridを指定します。その親をグリッドコンテナー、通常その直接の子をグリッドアイテムとして扱います。カードの中にある見出しや文章まで、外側のGridで自動的に横並びになるわけではありません。まずHTMLの入れ子を確認し、どの階層を並べたいかを決めることが大切です。

次の例では、cardsが親で、三つのarticleが直接の子です。各articleの中の見出しと段落はカードの内容です。親に列の定義を加えるとカードを並べられます。最初は装飾を少なくし、背景色や枠線で対象の境界を見えるようにすると、配置の仕組みを追いやすくなります。

<div class="cards">
  <article class="card">
    <h2>HTMLの構造</h2>
    <p>見出しと段落の役割を学びます。</p>
  </article>
  <article class="card">
    <h2>CSSの配置</h2>
    <p>行と列で要素を並べます。</p>
  </article>
  <article class="card">
    <h2>表示の確認</h2>
    <p>狭い画面と長い文章で試します。</p>
  </article>
</div>
.cards {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 1rem;
}
.card {
  padding: 1rem;
  border: 1px solid #8a9ba8;
  background: #f1f7f9;
}

Gridを有効にしただけで、希望する列数が自動的に決まると考えないようにします。列を定義しなければ、基本的には一列に並ぶ状態から始まります。上の例では三つの列を指定しているため、三枚のカードがそれぞれの列へ入ります。四枚目を追加したらどこへ入るかを試し、HTMLの順と自動配置の関係を観察しましょう。

行、列、線、トラックを別々に見る

Gridでは、行と列の区切りに線があります。隣り合う線の間の領域をトラックと呼び、行のトラックと列のトラックがあります。三列のグリッドなら、列を区切る線は四本です。配置を線番号で指定するときは、列そのものの番号ではなく線を基準にするため、この違いが重要になります。

MDNのCSSグリッドレイアウトの学習資料でも、行、列、トラック、間隔の基本が説明されています。文字だけで覚えにくい場合は、ブラウザーの開発者ツールでグリッドの線を表示します。どこに列があり、どのカードがどの領域へ入っているかを見れば、指定と結果を対応させやすくなります。

行の高さを指定しない場合、内容に応じて高さが決まる部分があります。短いカードだけで作った例では整って見えても、一枚だけ説明が長くなると見え方が変わります。早い段階で長い文章を一つ入れ、行の高さとカード内部の余白を観察してください。実際の内容に近い条件で試す方が、後から固定の高さを外す手戻りを減らせます。

※表は横にスクロールできます。

用語見る場所役割最初に試すこと
コンテナー並べる範囲の親グリッド全体を定義display:gridを付ける
アイテム通常は直接の子配置される要素カードを一つ増やす
列トラック縦の線と線の間横方向の幅を決める三列から二列へ変える
行トラック横の線と線の間縦方向の領域を決める長い内容を入れる
グリッド線トラックの境界配置の始点・終点開発者ツールで線を見る
gapトラック間行と列の間隔値を変えて余白を比べる

GridとFlexboxは、揃えたい関係から選ぶ

一方向へ並べることが中心ならFlexboxが扱いやすい場面があります。行と列をまたいで位置を揃えたい、ページ全体を領域に分けたい場合はGridを検討できます。どちらか一方ですべてを作る必要はありません。外側のカード一覧をGrid、カードの中のボタンと補足をFlexboxにするなど、役割に応じて組み合わせられます。

選ぶときは「横並びだからFlexbox」「複雑だからGrid」とだけ決めず、どの要素の関係を揃えたいかを言葉にします。たとえば、各行の列位置を共通にしたいならGridが説明しやすくなります。項目の幅に合わせて一列へ並べ、余った空間を配分したいならFlexboxが合うかもしれません。コードの短さだけではなく、後から内容が変わったときの直しやすさも考えます。

列幅と余白を決める|fr・repeat・minmaxの使い分け

列幅と余白を決める|fr・repeat・minmaxの使い分け(説明用生成イメージ)

frは残りの空間を分ける単位

frは、利用できる空間を比率で分けるために使います。1fr 1frなら同じ比率の二列、1fr 2frなら一対二の配分を意図した列になります。ただし、内容に由来する最小幅や他の固定幅、gapなどの条件が関わるため、どんな内容でも最終幅が常に単純な比率になると考えないようにしましょう。長い単語や画像がある場合は、後で説明する最小幅の確認が必要です。

固定幅とfrを組み合わせることもできます。補足欄を一定の幅にし、本文を残りへ広げたいときは、固定値とfrの列を作る方法があります。ただし、狭い画面では固定欄だけで幅を使い切る場合があります。PCでちょうどよい指定でも、そのままスマートフォンに適用せず、どの幅から一列へ変えるかを検討してください。

.layout {
  display: grid;
  grid-template-columns: 14rem minmax(0, 1fr);
  gap: 1.5rem;
}

この例では左側に14remの列を置き、右側が残りを使う設計です。右側の最小値を0とする指定は、内容に押されて列が広がる問題を調整する一つの方法です。ただし、長い文字列自体の折り返しや画像のサイズも別に整えます。列を縮めた結果、内容が外へはみ出していないかまで見て、必要な対策を選びましょう。

repeatで同じ列の繰り返しを表す

三つの同じ列を作るとき、1frを三回書く代わりにrepeat(3,1fr)と表せます。繰り返しの回数と列の定義が読み取りやすくなり、列数を変更するときも場所が分かりやすくなります。ただし、短く書けることだけを理由に複雑な指定を詰め込まないようにします。自分で説明できる範囲から使い始めることが大切です。

.equal-cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}
.equal-cards > * {
  min-width: 0;
  overflow-wrap: anywhere;
}

上のコードでは、列の最小値と、アイテム側の最小幅を明示しています。長い文字列には折り返しも指定していますが、すべての内容でこのまま使うべきという意味ではありません。たとえばコードや表を文字単位で折り返したくないなら、その要素だけ横スクロールにするなど別の設計が必要です。はみ出した内容をどう読める状態にするかまで考えてください。

minmaxで最小と最大の範囲を決める

minmaxは、トラックの最小と最大の大きさを組み合わせる関数です。MDNのminmaxリファレンスを参照しながら、最小値を固定にする場合と0にする場合を比べてみましょう。最小値を大きくすると、読みやすいカード幅を保ちやすい一方、親が狭いと入りきらなくなる可能性があります。

カード一覧で使うときは「カード一枚に最低どの程度の幅が必要か」を考えます。長い日本語の見出し、写真、ボタンがあるカードと、短いラベルだけのカードでは必要な幅が違います。数値を有名な作例からそのまま持ってくるのではなく、自分の内容が読みやすいかを見ながら調整してください。列の数より、一枚の内容が無理なく読めることを優先します。

※表は横にスクロールできます。

指定の例意図向く場面注意すること
1fr 1fr残りの空間を同じ比率で配分単純な二列内容の最小幅に影響される
14rem 1fr固定欄と可変欄を作る補足と本文狭い画面の切り替えが必要
repeat(3,1fr)同じ列を三回繰り返す列数が決まる一覧長い内容で幅が変わることがある
repeat(3,minmax(0,1fr))縮められる三列を定義均等列の土台内容のはみ出しも別途確認
minmax(16rem,1fr)最小幅を保ちながら広げる読みやすさを保つカード親の幅が最小値より小さい場合

gapと外側の余白を混ぜない

gapはトラック間の間隔です。カードの外周に同じ余白を付けたいなら、コンテナーのpaddingなどを別に考えます。カードごとにmarginを加え、さらにgapを指定すると、意図より広い間隔になる場合があります。どの余白が親の内側、カード間、カード内部なのかを分けて設計すると、数字を何度も調整する状態から抜け出しやすくなります。

行間と列間は、row-gapとcolumn-gapを分けて設定するか、gapの二つの値で指定できます。上から下へのまとまりと、横の比較を強調したい場合など、同じ値にする必要はありません。余白を変えたら、最終行の見え方と狭い画面の幅も確認します。列幅を固定したままgapを増やすと、全体が親の幅を超える場合があります。

要素を配置する|線番号・span・名前付きエリアを練習する

要素を配置する|線番号・span・名前付きエリアを練習する(説明用生成イメージ)

線番号は開始位置と終了位置を読む

三列のグリッドで、最初のカードを二列分使いたいなら、列の線1から線3までへ配置する考え方ができます。grid-column:1 / 3は、三列目まで使うという意味ではありません。開始の線と終了の線の間を使うため、二つの列をまたぐ指定になります。最初は線を表示しながら、どこからどこまでかを目で確認すると理解しやすくなります。

.gallery {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}
.gallery__lead {
  grid-column: 1 / 3;
}
.gallery__wide {
  grid-column: 1 / -1;
}

負の線番号は、明示したグリッドの終わり側から数えるときに使えます。この例の1 / -1は、明示した列の最初から最後までを使う意図です。ただし、後から暗黙の列を作るような指定を混ぜた場合も含めて、何でも全領域を覆うと単純化しないようにします。初心者の練習では、まず明示した三列の中だけで動きを確かめましょう。

列の指定を広げると、後に続くアイテムの自動配置も変わります。先頭のカードが二列を使えば、次のカードが入る場所は残りの領域になります。HTMLの順序を変えていないのに見た目が変わることを、カードへA、B、Cなどの文字を入れて確かめると分かりやすくなります。配置の指定は一つの要素だけでなく、周囲へも影響します。

spanはまたぐ数を示す

開始位置を固定せず、二列分の幅を使いたい場合はgrid-column:span 2のように表せます。どの列から始めるかを自動配置へ任せつつ、必要な幅を指定する考え方です。ただし、狭い画面で一列しか作っていないのに二列をまたぐ指定を残すと、意図しない列ができる原因になります。画面幅で列数を変えるときは、子の配置指定も一緒に見直してください。

行をまたぐ場合も、grid-rowへ同じ考え方を使えます。写真を大きく見せたいカードなどに役立ちますが、固定の行高を指定すると文章が増えたときに入りきらない場合があります。見た目のモザイクを作ることだけを目標にせず、カード内の情報が読めるか、操作の順番が自然かを確認しましょう。実際の文章を入れてから配置を確定させることが大切です。

名前付きエリアでページの構成を表す

本文、補足、ヘッダー、フッターのように役割が分かる配置では、grid-template-areasを使う方法があります。親に名前の並びを定義し、子にgrid-areaで対応する名前を指定します。数字だけで配置するより、ページの構成を読み取りやすくなる場面があります。MDNの名前付きエリアのガイドも確認してください。

.page {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(12rem, 1fr);
  grid-template-areas:
    "header header"
    "main   aside"
    "footer footer";
  gap: 1.25rem;
}
.page-header { grid-area: header; }
.page-main   { grid-area: main; }
.page-aside  { grid-area: aside; }
.page-footer { grid-area: footer; }

同じ名前の領域は、長方形のまとまりになるように定義します。曲がった形や離れた二か所へ同じ名前を置くなど、無効になる書き方をしないようにします。各行に書くセルの数も揃えます。動かないときはCSS全体を疑う前に、引用符、名前の綴り、行ごとの数を確認してください。空き領域を表したい場合の記法も、ガイドと照合しながら使います。

親の名前と子の名前が一致していることを確認します。たとえば親でmain、子でcontentと書けば、意図した対応になりません。クラス名とエリア名は同じである必要はありませんが、初めは関係が分かる名前を使うと間違いを減らせます。見た目を変える前に、各要素がどの領域へ対応するかを紙へ書く方法も有効です。

※表は横にスクロールできます。

配置方法指定する対象読み方見直す場面
grid-column:1 / 3列の開始線と終了線線1から線3まで線番号を列番号と混同したとき
grid-column:span 2またぐ列数二列分を使う一列レイアウトへ切り替えるとき
grid-row:span 2またぐ行数二行分を使う文章や画像の高さが変わるとき
grid-template-areas親の領域の並び名前で構成を表す画面幅で構成を変えるとき
grid-area:main子の配置先main領域へ入れる親と子の名前が一致しないとき

明示グリッドと暗黙グリッドを区別する

自分で列や行を定義した部分が明示グリッドです。アイテムが増えたり、定義した範囲の外へ配置したりすると、必要に応じて暗黙のトラックが作られます。予想外の余白や列が見えるときは、どこかの配置指定が外へはみ出していないかを確認します。子のspanや線番号を見直すと、原因を見つけられる場合があります。

暗黙の行の大きさはgrid-auto-rowsなどで調整できますが、問題を隠すために固定値を足さないようにします。まず、なぜ新しい行ができたのかを理解します。カードが増えて自然に次の行へ送られたのか、配置指定の誤りなのかで対応は違います。グリッド線を表示し、HTMLの順番とCSSの配置指定を照合する習慣が役立ちます。

画面幅へ対応する|カード一覧とページ構成を組む

画面幅へ対応する|カード一覧とページ構成を組む(説明用生成イメージ)

列数を自動で変えるカード一覧

カードが入る数を親の幅に合わせて変えたいときは、repeatとauto-fit、minmaxを組み合わせる方法があります。次の例では、カードが読みやすい最小幅を目安にしつつ、親がそれより狭いときにも収まりやすいように最小側へminを組み合わせています。16remは学習例の値で、実際の内容に応じて調整してください。

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 1.25rem;
}
.card {
  min-width: 0;
  padding: 1.25rem;
  border: 1px solid #9caeb5;
  border-radius: 0.75rem;
  background: #fff;
  overflow-wrap: anywhere;
}
.card img {
  display: block;
  max-width: 100%;
  height: auto;
}

この指定で列が切り替わる位置は、カードの最小幅だけでなく、gapや親のpaddingにも関わります。画面幅だけを見て「この数値なら必ず三列」と決めつけないようにしましょう。実際の親の利用可能な幅を開発者ツールで確認すると、切り替わりの理由が分かります。サイドバーの中へ同じ部品を置く場合など、画面幅と部品の幅が大きく違うことがあります。

auto-fitとauto-fillは、空いたトラックの扱いに違いがあります。要素が少ない場合にカードを広げたいのか、空き列の形を保ちたいのかによって選びます。違いを覚えるには、カードが一枚の状態と多数ある状態で両方を試すと分かりやすくなります。記事一覧で一枚だけ残ったときの見え方も、完成前に確認してください。

一つのHTMLで試せる練習ページ

次のコードを練習用ファイルとして保存すると、カードの配置をまとめて試せます。文章と列幅を変えて、どの条件で列数が変わるか観察します。外部の画像やライブラリを読み込まないため、内容の幅とGridの指定に集中できます。実案件のサイトへ直接貼り付けず、まず独立した練習ファイルで挙動を理解してください。

<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Gridカードの練習</title>
  <style>
    * { box-sizing: border-box; }
    body {
      margin: 0;
      color: #172b32;
      background: #edf3f5;
      font-family: system-ui, sans-serif;
      line-height: 1.7;
    }
    main {
      max-width: 72rem;
      margin-inline: auto;
      padding: 1.5rem;
    }
    h1 { font-size: clamp(1.5rem, 4vw, 2.25rem); }
    .cards {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
      gap: 1.25rem;
      list-style: none;
      padding: 0;
      margin: 1.5rem 0;
    }
    .card {
      min-width: 0;
      padding: 1.25rem;
      border: 1px solid #9caeb5;
      border-radius: 0.75rem;
      background: #fff;
      overflow-wrap: anywhere;
    }
    .card h2 { margin: 0 0 0.75rem; font-size: 1.2rem; }
    .card p { margin: 0; }
    .card a { color: #075e85; }
    .card a:focus-visible { outline: 3px solid #bd4a16; outline-offset: 4px; }
    .label { display: inline-block; margin-bottom: 0.75rem; font-weight: 700; }
  </style>
</head>
<body>
  <main>
    <h1>学習カードの配置を試す</h1>
    <p>画面幅と文章の長さを変えて、列数と折り返しを確認します。</p>
    <ul class="cards">
      <li class="card">
        <span class="label">課題1</span>
        <h2>親と子の関係</h2>
        <p>グリッドを定義した親と、その直接の子を確かめます。</p>
      </li>
      <li class="card">
        <span class="label">課題2</span>
        <h2>列幅と余白</h2>
        <p>最小幅を変えたとき、カードが並ぶ数と残りの空間がどう変わるかを観察します。</p>
      </li>
      <li class="card">
        <span class="label">課題3</span>
        <h2>長い内容を入れる</h2>
        <p>ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ</p>
      </li>
      <li class="card">
        <span class="label">課題4</span>
        <h2>情報の順番</h2>
        <p>CSSを外しても、HTMLの順で内容を理解できるか確認します。</p>
      </li>
    </ul>
  </main>
</body>
</html>

練習では、まずカードを一枚に減らし、次に五枚へ増やします。その後、一枚の文章だけを長くし、ブラウザーの幅を少しずつ変えます。同じCSSでも内容によって見え方が変わることを確認してください。修正する場合は、最小幅、gap、親のpaddingを一つずつ変え、何が列数に影響したかを記録すると理解が深まります。

ページ全体は構成の切り替えも考える

本文と補足を二列にするページでは、狭い幅で一列へ変える方が読みやすい場合があります。名前付きエリアなら、メディアクエリーの中で並びを再定義できます。切り替えの数値は特定の機種名だけで決めず、内容が窮屈になり始める幅を見て選びます。境界の直前と直後で表示を確認し、突然大きな余白やはみ出しが生まれていないか点検します。

@media (max-width: 48rem) {
  .page {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "header"
      "main"
      "aside"
      "footer";
  }
  .gallery__lead,
  .gallery__wide {
    grid-column: auto;
  }
}

この例の最後の指定は、別の練習例で設定した列またぎを解除する考え方を示しています。同じページで使う場合は、対象のクラスと実際の列定義が合うように整理してください。メディアクエリーだけを追加しても、子に残ったspanや固定幅が原因ではみ出す場合があります。親の列と子の配置を一組で見直すことが重要です。

崩れを直す|はみ出し・順序・検証のチェック手順

崩れを直す|はみ出し・順序・検証のチェック手順(説明用生成イメージ)

最終的に適用されたCSSを確認する

Gridの指定が効かないときは、最初にセレクターとHTMLのclassが一致しているかを見ます。次に、開発者ツールでdisplayが実際にgridになっているかを確認します。別のCSSが後から上書きしている場合、書いた内容と適用結果が違います。ファイルが読み込まれているか、キャッシュが古くないかも、変更が反映されないときの確認対象です。

その後、列定義、配置指定、幅の計算を順番に見ます。いきなり!importantを増やすと、原因を見つけないまま優先順位を強くすることになり、別の画面幅で問題が増える場合があります。不要な指定を一時的に外し、最小の構成で再現する方法が有効です。動く状態から一つずつ指定を戻すと、どの条件で崩れるかを説明しやすくなります。

はみ出しは内容と最小幅を分けて調べる

グリッドの外へ内容が出る場合は、列そのものが広がっているのか、列は収まっているが中身が出ているのかを区別します。長いURL、折り返されないコード、大きな画像、固定幅の表などが原因になります。グリッド線を表示すると、列の境界と内容の位置を比べられます。まず境界を見て、どこへ対策を入れるかを決めましょう。

minmax(0,1fr)やmin-width:0は、縮められる領域を作るための選択肢です。ただし、それだけで中の情報が読みやすくなるわけではありません。文字は適切に折り返し、画像は必要な幅へ収め、表やコードは必要に応じてスクロールできるようにします。overflow:hiddenで見えない部分を切るだけでは、必要な情報を失う可能性があります。

※表は横にスクロールできます。

症状最初の確認次に試すこと確認が終わる条件
一列のまま親のdisplayと列定義classと上書きCSSを見る意図した親に列ができる
横へはみ出す列境界と内容の幅最小幅・画像・長い文字を分ける情報を失わず幅に収まる
余分な列がある子の線番号とspan狭い画面の指定を解除する暗黙列が意図せず増えない
領域指定が効かないエリア名と長方形の定義行のセル数と綴りをそろえる各要素が指定領域へ入る
高さが足りない固定行高と文章量内容に応じた高さへ見直す文字の増加で欠けない
操作順が不自然HTML順と見た目の順無理な並べ替えを減らすキーボードでも自然に進む

見た目の順序と読む順序を合わせる

Gridは要素の見た目の位置を変えられますが、それだけでHTMLの意味の順番まで変わるとは限りません。キーボードで移動したときに、画面上の位置が飛び回る配置は使いにくくなります。MDNのGridとアクセシビリティの説明も確認し、まずHTMLを自然な順で組み、見た目の変更を必要な範囲へ絞ってください。

grid-auto-flow:denseなどで空き領域を埋める配置は、見た目の順番がHTMLの順とずれる可能性があります。写真だけの装飾的な一覧と、順番に読むべき手順では影響が違います。レイアウトを詰めることだけを優先せず、その要素が何を意味するかを考えます。見た目がきれいでも、内容を理解する順序を崩していないかを点検しましょう。

検証は幅だけでなく内容も変える

広い画面と狭い画面を一度ずつ見るだけでは、途中の幅で起こる崩れを見落とすことがあります。少しずつ幅を変え、列数が変わる付近でカードの文字やボタンを確認します。ブラウザーの拡大表示、長い見出し、画像の欠落、カードが一枚だけの状態も試します。実際のサイトでは、後から内容が追加されるため、最初の原稿だけで完成と判断しないことが大切です。

検証メモには、幅、内容の条件、起きた症状、変更した指定、再確認の結果を残します。「スマホで崩れた」だけより、「狭い親の中で二列spanが残り暗黙列ができた」と書けると、次回の調査が早くなります。修正後は、問題があった幅だけでなく広い幅も見直します。一か所の解決が別の画面を壊していないことまで確認してください。

CSS Gridを使った小さな作品ができ、コードの相談や体系的な学習を検討したい場合は、副業向けプログラミングスクールの料金と支援比較も判断材料になります。まず独学の練習で、配置の考え方、CSSの優先順位、検証のどこで困るかを整理し、質問できる範囲と教材の内容を比べましょう。受講したことだけで仕事を受けられるとは限りません。

Gridの基本は、親で行と列を定義し、子を意味のある順番で配置し、内容と画面幅が変わっても読めるかを確かめることです。最初は三枚のカードから始め、列数、余白、列またぎ、長い文章を一つずつ試してください。指定の名前を暗記するより、どの境界がどう変わったかを説明できることが、崩れを自分で直す力になります。