【CSS】Gridの使い方:Flexboxとの違いやレスポンシブ

css-grid

Gridは、Webサイトのレイアウトを縦横自在に操ることができるWeb制作におけるレイアウト手法です。

本記事では、Gridの基本概念、Flexboxとの使い分け、メディアクエリ不要で可変するレスポンシブ実装を解説します。

また、CSSに関するカテゴリーページから学びたい内容を決めたい人は、以下のCSSページをご確認ください。

目次

Gridとは:仕組みとFlexboxとの違い

gridを一言でいえば、Webページ上に透明な方眼紙(グリッド)を引き、要素を自由に配置していくシステムです。

ここでは、gridの使い方、Flexboxとの違いを解説します。

Gridとは:仕組みとFlexboxとの違い
  • 二次元(縦・横)レイアウトを作るGridの役割
  • GridとFlexboxの使い分け
  • 最新ブラウザ対応と古いブラウザのサポート

二次元(縦・横)レイアウトを作るGridの役割

Gridレイアウトの特徴は、縦(行)と横(列)の同時に制御できる二次元レイアウトである点です。

例えば、2行×2列のレイアウト、3カラムのレイアウトを作る際、HTMLの構造を複雑にすることなく、親要素のCSSだけで完結できます。

📐 CSS Gridによる3カラムレイアウト

※親要素のCSSだけで、子要素が綺麗に3列に並んでいます。

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
/* 💡 Gridコンテナ(親)の設定 */
.grid-container {
  display: grid;
  /* 1fr(均等な割合)を3列作る魔法の記述 */
  grid-template-columns: repeat(3, 1fr);
  gap: 15px; /* 縦横の隙間を一括指定 */
}
HTMLコード表示
<div class="grid-sec1-wrapper">
  <div class="grid-sec1-demo-area">
    <div class="grid-sec1-box">
      <div class="grid-sec1-label">📐 CSS Gridによる3カラムレイアウト</div>
      
      <div class="grid-sec1-visual">
        <p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
          ※親要素のCSSだけで、子要素が綺麗に3列に並んでいます。
        </p>

        <div class="grid-sec1-container">
          <div class="grid-sec1-item">Item 1</div>
          <div class="grid-sec1-item">Item 2</div>
          <div class="grid-sec1-item">Item 3</div>
          <div class="grid-sec1-item">Item 4</div>
          <div class="grid-sec1-item">Item 5</div>
          <div class="grid-sec1-item">Item 6</div>
        </div>
      </div>

      <div class="grid-sec1-code">
        /* 💡 Gridコンテナ(親)の設定 */<br>
        <span class="grid-hl-blue">.grid-container</span> {<br>
          <span class="grid-hl-green">display: grid;</span><br>
          <span class="grid-hl-comment">/* 1fr(均等な割合)を3列作る魔法の記述 */</span><br>
          <span class="grid-hl-red">grid-template-columns: repeat(3, 1fr);</span><br>
          <span class="grid-hl-green">gap: 15px;</span> /* 縦横の隙間を一括指定 */<br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.grid-sec1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.grid-sec1-demo-area {
  display: flex;
  justify-content: center;
}

.grid-sec1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.grid-sec1-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.grid-sec1-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

/* 💡 ここがGridの核となる設定 */
.grid-sec1-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 15px;
}

.grid-sec1-item {
  background-color: #0d6efd;
  color: #fff;
  font-weight: bold;
  padding: 20px;
  text-align: center;
  border-radius: 4px;
}

.grid-sec1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}

.grid-hl-green {
  color: #98c379;
  font-weight: bold;
}

.grid-hl-blue {
  color: #61afef;
  font-weight: bold;
}

.grid-hl-red {
  color: #e06c75;
  font-weight: bold;
}

.grid-hl-comment {
  color: #6c757d;
  font-style: italic;
}

displayプロパティの使い方を詳しく知りたい人は「【html&css】displayの種類は?flexやinline-blockの違い」を一読ください。

GridとFlexboxの使い分け

gridとflexの使い分けは重要です。

  • Grid
    ページ全体の大枠やカード一覧などの二次元(縦横)のマクロなレイアウトに使用します。
  • Flexbox
    カードの中にあるアイコンとテキストを横並びにするといった、一次元(横だけ、縦だけ)のミクロなレイアウトに使用します。
🤝 Grid(外枠)と Flexbox(中身)の組み合わせ
🍎 Apple

GridとFlexboxの組み合わせテスト

🍇 Grape

マクロとミクロの使い分け

/* 🏢 マクロな配置(外枠):CSS Grid */
.card-list {
  display: grid;
  grid-template-columns: 1fr 1fr; /* 2列 */
  gap: 20px;
}

/* 🛋 ミクロな配置(カードの中身):Flexbox */
.card-header {
  display: flex; /* 横並びにする */
  align-items: center; /* 縦の中央を揃える */
  gap: 10px; /* アイコンと文字の隙間 */
}
HTMLコード表示
<div class="grid-sec2-wrapper">
  <div class="grid-sec2-demo-area">
    <div class="grid-sec2-box">
      <div class="grid-sec2-label">🤝 Grid(外枠)と Flexbox(中身)の組み合わせ</div>
      
      <div class="grid-sec2-visual">
        <div class="grid-sec2-grid-wrap">
          
          <div class="grid-sec2-card">
            <div class="grid-sec2-card-header">
              <span class="grid-sec2-icon">🍎</span>
              <span class="grid-sec2-title">Apple</span>
            </div>
            <p class="grid-sec2-text">GridとFlexboxの組み合わせテスト</p>
          </div>

          <div class="grid-sec2-card">
            <div class="grid-sec2-card-header">
              <span class="grid-sec2-icon">🍇</span>
              <span class="grid-sec2-title">Grape</span>
            </div>
            <p class="grid-sec2-text">マクロとミクロの使い分け</p>
          </div>

        </div>
      </div>

      <div class="grid-sec1-code">
        /* 🏢 マクロな配置(外枠):CSS Grid */<br>
        <span class="grid-hl-blue">.card-list</span> {<br>
          <span class="grid-hl-green">display: grid;</span><br>
          <span class="grid-hl-red">grid-template-columns: 1fr 1fr;</span> /* 2列 */<br>
          <span class="grid-hl-green">gap: 20px;</span><br>
        }<br><br>

        /* 🛋 ミクロな配置(カードの中身):Flexbox */<br>
        <span class="grid-hl-blue">.card-header</span> {<br>
          <span class="grid-hl-green">display: flex;</span> /* 横並びにする */<br>
          <span class="grid-hl-red">align-items: center;</span> /* 縦の中央を揃える */<br>
          <span class="grid-hl-green">gap: 10px;</span> /* アイコンと文字の隙間 */<br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.grid-sec2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.grid-sec2-demo-area {
  display: flex;
  justify-content: center;
}

.grid-sec2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.grid-sec2-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.grid-sec2-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

/* 🏢 CSS Grid によるカードの並び(マクロ) */
.grid-sec2-grid-wrap {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}

.grid-sec2-card {
  background-color: #fff;
  border: 1px solid #ced4da;
  padding: 15px;
  border-radius: 8px;
}

/* 🛋 Flexbox によるカード内の要素の並び(ミクロ) */
.grid-sec2-card-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  border-bottom: 1px solid #f1f3f5;
  padding-bottom: 10px;
}

.grid-sec2-icon {
  font-size: 24px;
  background-color: #e9ecef;
  padding: 8px;
  border-radius: 50%;
}

.grid-sec2-title {
  font-size: 16px;
  font-weight: bold;
  color: #333;
}

.grid-sec2-text {
  font-size: 12px;
  color: #666;
  margin: 0;
  line-height: 1.5;
}

最新ブラウザ対応と古いブラウザのサポート

現在におけるgrid対応ブラウザは優秀で、Chrome、Safari、Edge、FirefoxなどのモダンブラウザではPC・スマホ問わず動作します。

Web制作において、Gridは「ガンガン使うべき標準技術」です。

もし、特殊な業務システムなどで古いブラウザを考慮する場合は、@supportsを使って、Gridが使えるブラウザにだけGridの設定を読み込ませるという処理を記述します。

🛡 @supports を使った機能の判別

現代ではIEを気にする必要はありませんが、新しいCSSプロパティ(今後登場するGridの進化版など)を使う際、ブラウザが対応しているかどうかを事前にチェックする @supports は非常に強力な武器になります。

/* 💡 ベースライン(古いブラウザ向けの設定を先に書く) */
.layout-box {
  display: block;
  /* 昔ながらの margin 等でレイアウトする記述… */
}

/* 💡 もし「display: grid」が使えるブラウザなら、ここを上書きする */
@supports (display: grid) {
  .layout-box {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
}
HTMLコード表示
<div class="grid-sec3-wrapper">
  <div class="grid-sec3-demo-area">
    <div class="grid-sec3-box">
      <div class="grid-sec3-label">🛡 @supports を使った機能の判別</div>
      
      <div class="grid-sec3-visual">
        <p style="font-size:13px; color:#333; line-height:1.6; margin:0;">
          現代ではIEを気にする必要はありませんが、新しいCSSプロパティ(今後登場するGridの進化版など)を使う際、ブラウザが対応しているかどうかを事前にチェックする <code>@supports</code> は非常に強力な武器になります。
        </p>
      </div>

      <div class="grid-sec1-code">
        /* 💡 ベースライン(古いブラウザ向けの設定を先に書く) */<br>
        <span class="grid-hl-blue">.layout-box</span> {<br>
          <span class="grid-hl-green">display: block;</span><br>
          <span class="grid-hl-comment">/* 昔ながらの margin 等でレイアウトする記述... */</span><br>
        }<br><br>

        /* 💡 もし「display: grid」が使えるブラウザなら、ここを上書きする */<br>
        <span class="grid-hl-red">@supports (display: grid)</span> {<br>
          <span class="grid-hl-blue">.layout-box</span> {<br>
            <span class="grid-hl-green">display: grid;</span><br>
            <span class="grid-hl-green">grid-template-columns: 1fr 1fr;</span><br>
          }<br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.grid-sec3-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.grid-sec3-demo-area {
  display: flex;
  justify-content: center;
}

.grid-sec3-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.grid-sec3-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.grid-sec3-visual {
  background-color: #e9ecef;
  padding: 20px;
  border-left: 4px solid #198754;
  border-radius: 4px;
  margin-bottom: 20px;
}

Gridレイアウトの作り方:親要素の設定

Gridの実装は、親要素となるgridコンテナを作ることから始まります。

親要素に対してdisplay: grid;を指定した瞬間に、子要素(グリッドアイテム)たちは配置のルールに従うようになります。

ここでは、グリッドプロパティ、実務で必須となる設定方法を詳しく見ていきましょう。

Gridレイアウトの作り方:親要素の設定
  • 列と行の数を決める基本
  • fr単位とは?比率で幅を指定する
  • gapプロパティでアイテム間の余白を作る

列と行の数を決める基本

グリッドの設計図を描くために重要なのが、grid-templateの設定です。

具体的には、縦の列の数と幅を決めるgrid-template-columns、横の行の数と高さを決めるgrid-template-rowsを使用します。

これによって、グリッドの列数を操ることができます。

📐 列(columns)と行(rows)の基本

※幅100pxの列を3つ作り、1行目の高さだけ50pxに指定した例です。
4つ目のアイテムは自動的に次の行へ押し出されます。

1
2
3
4 (自動折り返し)
/* 💡 Gridコンテナの設定 */
.container {
  display: grid;
  /* 100px幅の列を3つ作る */
  grid-template-columns: 100px 100px 100px;
  /* 1行目の高さを50pxに固定する */
  grid-template-rows: 50px;
  gap: 10px;
}
HTMLコード表示
<div class="grid-sec4-wrapper">
  <div class="grid-sec4-demo-area">
    <div class="grid-sec4-box">
      <div class="grid-sec4-label">📐 列(columns)と行(rows)の基本</div>
      
      <div class="grid-sec4-visual">
        <p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
          ※幅100pxの列を3つ作り、1行目の高さだけ50pxに指定した例です。<br>
          4つ目のアイテムは自動的に次の行へ押し出されます。
        </p>

        <div class="grid-sec4-container">
          <div class="grid-sec4-item">1</div>
          <div class="grid-sec4-item">2</div>
          <div class="grid-sec4-item">3</div>
          <div class="grid-sec4-item" style="background-color:#198754;">4 (自動折り返し)</div>
        </div>
      </div>

      <div class="grid-sec4-code">
        /* 💡 Gridコンテナの設定 */<br>
        <span class="grid-hl-blue">.container</span> {<br>
          <span class="grid-hl-green">display: grid;</span><br>
          <span class="grid-hl-comment">/* 100px幅の列を3つ作る */</span><br>
          <span class="grid-hl-red">grid-template-columns: 100px 100px 100px;</span><br>
          <span class="grid-hl-comment">/* 1行目の高さを50pxに固定する */</span><br>
          <span class="grid-hl-red">grid-template-rows: 50px;</span><br>
          <span class="grid-hl-green">gap: 10px;</span><br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.grid-sec4-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.grid-sec4-demo-area {
  display: flex;
  justify-content: center;
}

.grid-sec4-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.grid-sec4-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.grid-sec4-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* 💡 コンテナの基本設定 */
.grid-sec4-container {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 50px;
  gap: 10px;
  background-color: #e9ecef;
  padding: 10px;
  border: 1px dashed #adb5bd;
}

.grid-sec4-item {
  background-color: #0d6efd;
  color: #fff;
  font-weight: bold;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  font-size: 14px;
  /* 高さが指定されていない行は中身に合わせて自動(auto)になります */
  padding: 10px; 
}

.grid-sec4-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}

.grid-hl-green {
  color: #98c379;
  font-weight: bold;
}

.grid-hl-blue {
  color: #61afef;
  font-weight: bold;
}

.grid-hl-red {
  color: #e06c75;
  font-weight: bold;
}

.grid-hl-comment {
  color: #6c757d;
  font-style: italic;
}

fr単位とは?比率で幅を指定する

Gridで画期的と言えるのが「fr」という単位です。

これは「Fraction(分数・比率)」の略です。

画面の幅から固定値(pxなど)を引いた後の残りのスペースを指定した数値の比率で分け合います。

例えば、「1fr」と「2fr」を組み合わせれば、1:2の比率で伸縮するレイアウトが作れます。

レスポンシブデザインではfrを主役に使いましょう。

frは隙間の分を自動で差し引いてから比率を計算するため、レイアウト崩れが減ります。

⚖️ 「fr」単位による比率(2:1)のレイアウト

※隙間(gap)を引いた残りのスペースを、2対1の比率で美しく分割しています。

メインコンテンツ
(2fr)
サイドバー
(1fr)
/* 💡 コンテナにfr(比率)を設定 */
.layout-container {
  display: grid;
  /* 画面幅に応じて常に 2 : 1 の幅をキープする */
  grid-template-columns: 2fr 1fr;
  gap: 20px; /* 隙間の分は自動で計算から引かれる */
}
HTMLコード表示
<div class="grid-sec5-wrapper">
  <div class="grid-sec5-demo-area">
    <div class="grid-sec5-box">
      <div class="grid-sec5-label">⚖️ 「fr」単位による比率(2:1)のレイアウト</div>
      
      <div class="grid-sec5-visual">
        <p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
          ※隙間(gap)を引いた残りのスペースを、2対1の比率で美しく分割しています。
        </p>

        <div class="grid-sec5-container">
          <div class="grid-sec5-item grid-sec5-main">
            メインコンテンツ<br>
            <span style="font-size:11px;">(2fr)</span>
          </div>
          <div class="grid-sec5-item grid-sec5-side">
            サイドバー<br>
            <span style="font-size:11px;">(1fr)</span>
          </div>
        </div>
      </div>

      <div class="grid-sec5-code">
        /* 💡 コンテナにfr(比率)を設定 */<br>
        <span class="grid-hl-blue">.layout-container</span> {<br>
          <span class="grid-hl-green">display: grid;</span><br>
          <span class="grid-hl-comment">/* 画面幅に応じて常に 2 : 1 の幅をキープする */</span><br>
          <span class="grid-hl-red">grid-template-columns: 2fr 1fr;</span><br>
          <span class="grid-hl-green">gap: 20px;</span> /* 隙間の分は自動で計算から引かれる */<br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.grid-sec5-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.grid-sec5-demo-area {
  display: flex;
  justify-content: center;
}

.grid-sec5-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.grid-sec5-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.grid-sec5-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

/* 💡 frを使った可変レイアウト */
.grid-sec5-container {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 20px;
}

.grid-sec5-item {
  color: #fff;
  font-weight: bold;
  padding: 40px 20px;
  text-align: center;
  border-radius: 4px;
}

.grid-sec5-main {
  background-color: #198754;
}

.grid-sec5-side {
  background-color: #6c757d;
}

.grid-sec5-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}

gapプロパティでアイテム間の余白を作る

かつては要素間の「隙間」を作るため、子要素にmarginをつけて端だけ消す…という面倒な作業が必要でした。

しかしGridでは、親要素に「gap」を指定するだけです。

「gridの余白」を調整するこのプロパティは、縦横一括のgapだけでなく、列の間隔と行の間隔を個別に指定することも可能です。

🔲 縦横の「gap」を個別に指定する

※行(縦)の隙間を20px、列(横)の隙間を40pxと、別々に指定した例です。
アイテム同士の間にだけ適用され、外側には余白ができません。

A
B
C
D
/* 💡 縦横の隙間を一括、または別々に指定する */
.gap-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* 個別に指定する場合 */
  row-gap: 20px; /* 行(縦)の隙間 */
  column-gap: 40px; /* 列(横)の隙間 */
  /* ※一括で「gap: 20px 40px;」と書くことも可能 */
}
HTMLコード表示
<div class="grid-sec6-wrapper">
  <div class="grid-sec6-demo-area">
    <div class="grid-sec6-box">
      <div class="grid-sec6-label">🔲 縦横の「gap」を個別に指定する</div>
      
      <div class="grid-sec6-visual">
        <p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
          ※行(縦)の隙間を20px、列(横)の隙間を40pxと、別々に指定した例です。<br>
          アイテム同士の間にだけ適用され、外側には余白ができません。
        </p>

        <div class="grid-sec6-container">
          <div class="grid-sec6-item">A</div>
          <div class="grid-sec6-item">B</div>
          <div class="grid-sec6-item">C</div>
          <div class="grid-sec6-item">D</div>
        </div>
      </div>

      <div class="grid-sec6-code">
        /* 💡 縦横の隙間を一括、または別々に指定する */<br>
        <span class="grid-hl-blue">.gap-container</span> {<br>
          <span class="grid-hl-green">display: grid;</span><br>
          <span class="grid-hl-green">grid-template-columns: 1fr 1fr;</span><br>
          <span class="grid-hl-comment">/* 個別に指定する場合 */</span><br>
          <span class="grid-hl-red">row-gap: 20px;</span> /* 行(縦)の隙間 */<br>
          <span class="grid-hl-red">column-gap: 40px;</span> /* 列(横)の隙間 */<br>
          <span class="grid-hl-comment">/* ※一括で「gap: 20px 40px;」と書くことも可能 */</span><br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.grid-sec6-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.grid-sec6-demo-area {
  display: flex;
  justify-content: center;
}

.grid-sec6-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.grid-sec6-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.grid-sec6-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

/* 💡 gapの個別指定 */
.grid-sec6-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  row-gap: 20px;
  column-gap: 40px;
  /* 隙間が分かりやすいように背景に斜線を入れる(疑似的) */
  background: repeating-linear-gradient(
    45deg,
    #e9ecef,
    #e9ecef 10px,
    #dee2e6 10px,
    #dee2e6 20px
  );
  padding: 10px; /* これは外枠との余白 */
  border: 1px solid #ced4da;
}

.grid-sec6-item {
  background-color: #ffc107;
  color: #333;
  font-weight: bold;
  padding: 30px 20px;
  text-align: center;
  border-radius: 4px;
  font-size: 18px;
}

.grid-sec6-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}

子要素の配置と結合

親要素で「方眼紙」を作ったら、そのマス目の中に「グリッドアイテム」をどのように配置していくかを決定します。

Gridの力は、「1つのマス目」に対する自由な操作性にあります。

ここでは、実務で必須となるマスの結合、Flexboxよりも簡単な中央寄せ、絶対配置(position: absolute)を使わずに要素を重ねるテクニックを解説します。

子要素の配置と結合
  • 指定したエリアに配置する
  • 縦横の中央寄せと配置の調整
  • 表示順番の変更と重なりの制御

指定したエリアに配置する

要素を複数のマスにまたがって配置するgrid結合には、主に2つのアプローチがあります。

1つは、グリッドの線(ライン番号)を指定して横方向の結合や縦方向の結合を行う方法です。

もう1つは、直感的に名前をつけてパズルように配置するgrid-template-areasを使う方法です。

🧩 エリアの命名と結合(grid-template-areas)

※ヘッダーは横に全画面、サイドバーは縦に配置する王道レイアウトです。

Header (結合)
Sidebar
Main Content
/* 💡 親要素:パズルの枠組みを作る */
.container {
  display: grid;
  grid-template-columns: 1fr 2fr;
  grid-template-areas:
    “header header” /* 1行目は全部ヘッダー */
    “sidebar main” /* 2行目はサイドとメイン */
    “footer footer”; /* 3行目は全部フッター */
}

/* 💡 子要素:自分の名前を宣言するだけ! */
.header {
  grid-area: header;
}
.main {
  grid-area: main;
}
HTMLコード表示
<div class="item-sec1-wrapper">
  <div class="item-sec1-demo-area">
    <div class="item-sec1-box">
      <div class="item-sec1-label">🧩 エリアの命名と結合(grid-template-areas)</div>
      
      <div class="item-sec1-visual">
        <p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
          ※ヘッダーは横に全画面、サイドバーは縦に配置する王道レイアウトです。
        </p>

        <div class="item-sec1-container">
          <div class="item-sec1-item item-sec1-header">Header (結合)</div>
          <div class="item-sec1-item item-sec1-sidebar">Sidebar</div>
          <div class="item-sec1-item item-sec1-main">Main Content</div>
          <div class="item-sec1-item item-sec1-footer">Footer (結合)</div>
        </div>
      </div>

      <div class="item-sec1-code">
        /* 💡 親要素:パズルの枠組みを作る */<br>
        <span class="item-hl-blue">.container</span> {<br>
          <span class="item-hl-green">display: grid;</span><br>
          <span class="item-hl-green">grid-template-columns: 1fr 2fr;</span><br>
          <span class="item-hl-red">grid-template-areas:</span><br>
            <span class="item-hl-red">"header  header"</span> /* 1行目は全部ヘッダー */<br>
            <span class="item-hl-red">"sidebar main"</span>   /* 2行目はサイドとメイン */<br>
            <span class="item-hl-red">"footer  footer";</span> /* 3行目は全部フッター */<br>
        }<br><br>

        /* 💡 子要素:自分の名前を宣言するだけ! */<br>
        <span class="item-hl-blue">.header</span> {<br>
          <span class="item-hl-green">grid-area: header;</span><br>
        }<br>
        <span class="item-hl-blue">.main</span> {<br>
          <span class="item-hl-green">grid-area: main;</span><br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.item-sec1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.item-sec1-demo-area {
  display: flex;
  justify-content: center;
}

.item-sec1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.item-sec1-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.item-sec1-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

/* 💡 Gridコンテナ(名前で配置) */
.item-sec1-container {
  display: grid;
  grid-template-columns: 1fr 2fr;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  gap: 10px;
}

.item-sec1-item {
  color: #fff;
  font-weight: bold;
  padding: 20px;
  text-align: center;
  border-radius: 4px;
}

/* 各エリアへの割り当て */
.item-sec1-header {
  grid-area: header;
  background-color: #0d6efd;
}
.item-sec1-sidebar {
  grid-area: sidebar;
  background-color: #6c757d;
}
.item-sec1-main {
  grid-area: main;
  background-color: #198754;
  height: 100px; /* メインエリアの高さを出す */
  display: flex;
  align-items: center;
  justify-content: center;
}
.item-sec1-footer {
  grid-area: footer;
  background-color: #343a40;
}

.item-sec1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}

.item-hl-green { color: #98c379; font-weight: bold; }
.item-hl-blue { color: #61afef; font-weight: bold; }
.item-hl-red { color: #e06c75; font-weight: bold; }

縦横の中央寄せと配置の調整

長年、CSSにおける上下左右の中央寄せは複雑で面倒なものでした。

しかし、Gridの登場により1行のコードで実現可能になりました。

マス目の中での要素の配置は、横方向をjustify-items、縦方向をalign-itemsで制御します。

これらをまとめて中央寄せにするショートハンド(一括指定)がplace-itemsです。

🎯 上下左右の中央寄せ(place-items)
デフォルト (stretch)
中央寄せ (center)
/* 💡 これだけでマス目のど真ん中に配置されます */
.cell-center {
  display: grid;
  place-items: center; /* 💡 justifyとalignを同時に指定 */
}

/* ※上記は以下の2行と全く同じ意味です */
/* justify-items: center; */
/* align-items: center; */
HTMLコード表示
<div class="item-sec2-wrapper">
  <div class="item-sec2-demo-area">
    <div class="item-sec2-box">
      <div class="item-sec2-label">🎯 上下左右の中央寄せ(place-items)</div>
      
      <div class="item-sec2-visual">
        <div class="item-sec2-grid">
          
          <div class="item-sec2-cell">
            <span class="item-sec2-badge">デフォルト (stretch)</span>
          </div>
          
          <div class="item-sec2-cell item-sec2-center">
            <span class="item-sec2-badge item-sec2-badge-green">中央寄せ (center)</span>
          </div>

        </div>
      </div>

      <div class="item-sec1-code">
        /* 💡 これだけでマス目のど真ん中に配置されます */<br>
        <span class="item-hl-blue">.cell-center</span> {<br>
          <span class="item-hl-green">display: grid;</span><br>
          <span class="item-hl-red">place-items: center;</span> /* 💡 justifyとalignを同時に指定 */<br>
        }<br><br>

        /* ※上記は以下の2行と全く同じ意味です */<br>
        <span class="item-hl-comment">/* justify-items: center; */</span><br>
        <span class="item-hl-comment">/* align-items: center; */</span>
      </div>
    </div>
  </div>
</div>
CSSコード表示
.item-sec2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.item-sec2-demo-area {
  display: flex;
  justify-content: center;
}

.item-sec2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.item-sec2-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.item-sec2-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

.item-sec2-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 15px;
}

.item-sec2-cell {
  background-color: #fff;
  border: 2px dashed #adb5bd;
  height: 120px;
  border-radius: 4px;
  /* 左側のデフォルトは指定なし(stretch) */
}

.item-sec2-badge {
  background-color: #6c757d;
  color: #fff;
  padding: 10px 15px;
  border-radius: 50px;
  font-size: 13px;
  font-weight: bold;
}

/* 💡 マス目の中央に配置 */
.item-sec2-center {
  display: grid;
  place-items: center;
}

.item-sec2-badge-green {
  background-color: #198754;
}

.item-hl-comment {
  color: #6c757d;
  font-style: italic;
}

表示順番の変更と重なりの制御

HTMLの記述順序を変えることなく、画面上の順番だけを変更するプロパティがorderです。

スマホ表示とPC表示でコンテンツの左右を入れ替えたい時などに重宝します。

さらに、Gridには同じマス目に複数の要素を配置するという機能があります。

これを利用すればposition: absolute;を使わずに、画像の上にテキストを重ねることができ、z-indexで重なりの優先順位を制御できます。

🥞 同じマスに要素を重ねる(z-indexの活用)

※position:absoluteを使わず、同じ「1行1列目」に画像と文字を配置して重ねています。

Image Layer
Overlapping Text
/* 💡 コンテナは1マスだけ作る */
.overlap-container {
  display: grid;
}

/* 💡 全く同じ「1行目の1列目」に両方を配置する */
.bg-layer {
  grid-area: 1 / 1; /* 1行1列目 */
  z-index: 1; /* 下の層 */
}

.text-layer {
  grid-area: 1 / 1; /* 💡 同じ場所に配置すると重なる! */
  z-index: 2; /* 上の層 */
  align-self: end; /* 下端に寄せる */
}
HTMLコード表示
<div class="item-sec3-wrapper">
  <div class="item-sec3-demo-area">
    <div class="item-sec3-box">
      <div class="item-sec3-label">🥞 同じマスに要素を重ねる(z-indexの活用)</div>
      
      <div class="item-sec3-visual">
        <p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
          ※position:absoluteを使わず、同じ「1行1列目」に画像と文字を配置して重ねています。
        </p>

        <div class="item-sec3-overlap-container">
          <div class="item-sec3-bg-layer">Image Layer</div>
          <div class="item-sec3-text-layer">Overlapping Text</div>
        </div>
      </div>

      <div class="item-sec1-code">
        /* 💡 コンテナは1マスだけ作る */<br>
        <span class="item-hl-blue">.overlap-container</span> {<br>
          <span class="item-hl-green">display: grid;</span><br>
        }<br><br>

        /* 💡 全く同じ「1行目の1列目」に両方を配置する */<br>
        <span class="item-hl-blue">.bg-layer</span> {<br>
          <span class="item-hl-green">grid-area: 1 / 1;</span> /* 1行1列目 */<br>
          <span class="item-hl-red">z-index: 1;</span> /* 下の層 */<br>
        }<br><br>
        
        <span class="item-hl-blue">.text-layer</span> {<br>
          <span class="item-hl-green">grid-area: 1 / 1;</span> /* 💡 同じ場所に配置すると重なる! */<br>
          <span class="item-hl-red">z-index: 2;</span> /* 上の層 */<br>
          <span class="item-hl-green">align-self: end;</span> /* 下端に寄せる */<br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.item-sec3-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.item-sec3-demo-area {
  display: flex;
  justify-content: center;
}

.item-sec3-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.item-sec3-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.item-sec3-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
  display: flex;
  justify-content: center;
}

/* 💡 コンテナ設定 */
.item-sec3-overlap-container {
  display: grid;
  width: 250px;
  height: 150px;
  border-radius: 8px;
  overflow: hidden;
}

/* 💡 下の層(背景画像代わり) */
.item-sec3-bg-layer {
  grid-area: 1 / 1; /* 1行目の1列目 */
  z-index: 1;
  background-color: #0d6efd;
  color: rgba(255,255,255,0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  font-size: 20px;
}

/* 💡 上の層(テキスト) */
.item-sec3-text-layer {
  grid-area: 1 / 1; /* ★全く同じ場所に指定する★ */
  z-index: 2;
  align-self: end; /* マスの下端に配置 */
  background-color: rgba(0, 0, 0, 0.7);
  color: #fff;
  padding: 10px;
  text-align: center;
  font-weight: bold;
  font-size: 14px;
}

要素の重なり順を決めるz-indexプロパティの使い方を詳しく知りたい人は「【html&css】z-indexとは?使い方と効かない時の対処」を一読ください。

Gridにおけるrepeat()・auto-fit・minmax

Web制作において重宝されるのが、「メディアクエリ(@media)を使わずに画面幅に合わせてレイアウトを変える」テクニックです。

レスポンシブを実現するには、手作業で列の幅を計算するのではなく、ブラウザに計算を丸投げする関数を組み合わせます。

Gridにおけるrepeat()・auto-fit・minmax
  • repeat()を使って可変カラムを作る
  • auto-fitauto-fillの違い
  • minmax()を使った最小幅・最大幅の自動計算

repeat()を使って可変カラムを作る

「2カラム」や「3 列カラム」などを作る際、1fr 1fr 1frと何度も書くのは非効率です。

そこで登場するのが、繰り返しを簡略化するrepeat()関数です。

🔁 repeat() による列の作成

※「1fr」を3回繰り返す(repeat(3, 1fr))設定です。

1
2
3
4
5
/* 💡 同じ幅を繰り返す */
.grid-container {
  display: grid;
  /* 1fr 1fr 1fr と書くのと同じ意味 */
  grid-template-columns: repeat(3, 1fr);
  gap: 15px;
}
HTMLコード表示
<div class="res-sec1-wrapper">
  <div class="res-sec1-demo-area">
    <div class="res-sec1-box">
      <div class="res-sec1-label">🔁 repeat() による列の作成</div>
      
      <div class="res-sec1-visual">
        <p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
          ※「1fr」を3回繰り返す(repeat(3, 1fr))設定です。
        </p>

        <div class="res-sec1-container">
          <div class="res-sec1-item">1</div>
          <div class="res-sec1-item">2</div>
          <div class="res-sec1-item">3</div>
          <div class="res-sec1-item">4</div>
          <div class="res-sec1-item">5</div>
        </div>
      </div>

      <div class="res-sec1-code">
        /* 💡 同じ幅を繰り返す */<br>
        <span class="res-hl-blue">.grid-container</span> {<br>
          <span class="res-hl-green">display: grid;</span><br>
          <span class="res-hl-comment">/* 1fr 1fr 1fr と書くのと同じ意味 */</span><br>
          <span class="res-hl-red">grid-template-columns: repeat(3, 1fr);</span><br>
          <span class="res-hl-green">gap: 15px;</span><br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.res-sec1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.res-sec1-demo-area {
  display: flex;
  justify-content: center;
}

.res-sec1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.res-sec1-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.res-sec1-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

.res-sec1-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 15px;
}

.res-sec1-item {
  background-color: #0d6efd;
  color: #fff;
  font-weight: bold;
  padding: 20px;
  text-align: center;
  border-radius: 4px;
}

.res-sec1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}

.res-hl-green { color: #98c379; font-weight: bold; }
.res-hl-blue { color: #61afef; font-weight: bold; }
.res-hl-red { color: #e06c75; font-weight: bold; }
.res-hl-comment { color: #6c757d; font-style: italic; }

auto-fitとauto-fillの違い

「画面が狭くなったら2列に、さらに狭くなったら1列に…」というレスポンシブを自動で行ってくれるのがauto-fitauto-fillキーワードです。

repeat(3, ...)の「3(固定数)」の部分をこのキーワードに置き換えるだけで、ブラウザが親要素の幅に合わせて「入るだけ」の列を計算して作ります。

カード一覧やギャラリーなど、アイテムを画面いっぱいに敷き詰めたい実務のケースではauto-fitを使用します。

迷ったらauto-fitを選べば間違いありません。

📏 auto-fit と auto-fill の違い

※アイテム数が少ない時(今回は2個)の挙動の違いです。

△ auto-fill(余白が余る)

1
2

⭕️ auto-fit(実務で多用・全体に広がる)

1
2
/* △ auto-fill:空のマスを作ってスペースを埋める */
.grid-fill {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}

/* ⭕️ auto-fit:アイテムを引き伸ばしてフィットさせる */
.grid-fit {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}
HTMLコード表示
<div class="res-sec2-wrapper">
  <div class="res-sec2-demo-area">
    <div class="res-sec2-box">
      <div class="res-sec2-label">📏 auto-fit と auto-fill の違い</div>
      
      <div class="res-sec2-visual">
        <p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
          ※アイテム数が少ない時(今回は2個)の挙動の違いです。
        </p>

        <div style="margin-bottom: 20px;">
          <p style="font-size:13px; font-weight:bold; color:#dc3545; margin:0 0 5px 0;">△ auto-fill(余白が余る)</p>
          <div class="res-sec2-container res-sec2-fill">
            <div class="res-sec2-item">1</div>
            <div class="res-sec2-item">2</div>
          </div>
        </div>

        <div>
          <p style="font-size:13px; font-weight:bold; color:#198754; margin:0 0 5px 0;">⭕️ auto-fit(実務で多用・全体に広がる)</p>
          <div class="res-sec2-container res-sec2-fit">
            <div class="res-sec2-item" style="background-color:#198754;">1</div>
            <div class="res-sec2-item" style="background-color:#198754;">2</div>
          </div>
        </div>
      </div>

      <div class="res-sec1-code">
        /* △ auto-fill:空のマスを作ってスペースを埋める */<br>
        <span class="res-hl-blue">.grid-fill</span> {<br>
          <span class="res-hl-green">display: grid;</span><br>
          <span class="res-hl-red">grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));</span><br>
        }<br><br>

        /* ⭕️ auto-fit:アイテムを引き伸ばしてフィットさせる */<br>
        <span class="res-hl-blue">.grid-fit</span> {<br>
          <span class="res-hl-green">display: grid;</span><br>
          <span class="res-hl-red">grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));</span><br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.res-sec2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.res-sec2-demo-area {
  display: flex;
  justify-content: center;
}

.res-sec2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.res-sec2-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.res-sec2-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

.res-sec2-container {
  display: grid;
  gap: 10px;
  background-color: #e9ecef;
  border: 1px dashed #adb5bd;
  padding: 10px;
}

/* 違いを生み出すプロパティ */
.res-sec2-fill {
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}

.res-sec2-fit {
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}

.res-sec2-item {
  background-color: #6c757d;
  color: #fff;
  font-weight: bold;
  padding: 15px;
  text-align: center;
  border-radius: 4px;
}

minmax()を使った最小幅・最大幅の自動計算

auto-fitとセットで使われるのがminmax関数です。

文字通り、「アイテムの幅の最小値と最大値」を決める関数です。

Gridでレスポンシブな一覧を作る1行がgrid-template-columns: repeat(auto-fit, minmax(280px, 1fr));です。

minmax(280px, 1fr)の意味は「アイテムの幅は280px(最小値=固定値) は確保しなさい。画面に余裕があるなら1fr(最大値=可変割合) まで大きく広がりなさい」ということです。

これをauto-fitで繰り返すことで、「画面幅に余裕があれば3列や4列になり、画面が縮んで280px以下になりそうになったら、自動で段組みを折り返して280px以上をキープする」というレスポンシブがメディアクエリなしで実現します。

🏆 メディアクエリ不要の黄金コード

※最低幅が150pxに設定されています。プレビュー領域の都合上、すでに2列に折り返されている場合がありますが、どんな幅でもはみ出さずに自動整列します。

カード 1
カード 2
カード 3
カード 4
/* 💡 実務で最も使われる黄金の1行 */
.card-list {
  display: grid;
  gap: 20px;
  /* 自動で列数を調整し、最低幅を下回ったら折り返す */
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
HTMLコード表示
<div class="res-sec3-wrapper">
  <div class="res-sec3-demo-area">
    <div class="res-sec3-box">
      <div class="res-sec3-label">🏆 メディアクエリ不要の黄金コード</div>
      
      <div class="res-sec3-visual">
        <p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
          ※最低幅が150pxに設定されています。プレビュー領域の都合上、すでに2列に折り返されている場合がありますが、どんな幅でもはみ出さずに自動整列します。
        </p>

        <div class="res-sec3-container">
          <div class="res-sec3-item">カード 1</div>
          <div class="res-sec3-item">カード 2</div>
          <div class="res-sec3-item">カード 3</div>
          <div class="res-sec3-item">カード 4</div>
        </div>
      </div>

      <div class="res-sec1-code">
        /* 💡 実務で最も使われる黄金の1行 */<br>
        <span class="res-hl-blue">.card-list</span> {<br>
          <span class="res-hl-green">display: grid;</span><br>
          <span class="res-hl-green">gap: 20px;</span><br>
          <span class="res-hl-comment">/* 自動で列数を調整し、最低幅を下回ったら折り返す */</span><br>
          <span class="res-hl-red">grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));</span><br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.res-sec3-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.res-sec3-demo-area {
  display: flex;
  justify-content: center;
}

.res-sec3-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.res-sec3-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.res-sec3-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

/* 💡 コードの実装(デモ用にminmaxは150pxにしています) */
.res-sec3-container {
  display: grid;
  gap: 15px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.res-sec3-item {
  background-color: #0d6efd;
  color: #fff;
  font-weight: bold;
  padding: 30px 10px;
  text-align: center;
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}

実用レイアウト集:コピペで使えるGridサンプル

Gridの基本ルールを理解したら、実務で使える実践的なレイアウトを作っていきましょう。

ここでは、gridサンプルとしてWebサイトで頻出する3つのレイアウトパターンをご紹介します。

よく使う形を「gridチートシート」としてストックしておくと、開発スピードが向上します。

そのままコピペして、デザインを調整してご活用ください。

実用レイアウト集:コピペで使えるGridサンプル
  • 定番のヘッダー・メイン・フッター
  • タイル状の画像ギャラリーとカードレイアウト
  • Masonry(Pinterest風)や複雑なグリッド

定番のヘッダー・メイン・フッター

Webサイトの基本的な構造である「ヘッダー、サイドバー、メインコンテンツ、フッター」を組み合わせたレイアウトです。

Gridを使って画面全体をレイアウトする際は、親要素にmin-height: 100vh;(最低でも画面の高さ100%にする)を指定し、grid-template-rows: auto 1fr auto;と設定します。

これにより、ヘッダーとフッターは中身の高さ(auto)になり、メインコンテンツは残りの余白を吸収して伸びる(1fr)ため、中身が少なくてもフッターが画面の最下部に張り付くレイアウトが完成します。

🏛 ヘッダー・メイン・フッター

※メインコンテンツの量が少なくても、フッターが必ず一番下(プレビュー枠の下端)に配置されます。

Header (auto)
Main Content
(1fr・残りをすべて埋める)
Footer (auto)
/* 💡 縦方向の骨格(フッターを一番下に落とす) */
.layout-wrapper {
  display: grid;
  min-height: 100vh; /* 画面の高さを確保 */
  /* ヘッダー:中身次第、 メイン:残り全部、 フッター:中身次第 */
  grid-template-rows: auto 1fr auto;
}

/* 💡 真ん中のエリア(サイドバーとメイン)を横並びに */
.middle-area {
  display: grid;
  grid-template-columns: 200px 1fr; /* サイドは固定、メインは可変 */
}
HTMLコード表示
<div class="ex-sec1-wrapper">
  <div class="ex-sec1-demo-area">
    <div class="ex-sec1-box">
      <div class="ex-sec1-label">🏛 ヘッダー・メイン・フッター</div>
      
      <div class="ex-sec1-visual">
        <p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
          ※メインコンテンツの量が少なくても、フッターが必ず一番下(プレビュー枠の下端)に配置されます。
        </p>

        <div class="ex-sec1-layout">
          <header class="ex-sec1-header">Header (auto)</header>
          
          <div class="ex-sec1-middle">
            <nav class="ex-sec1-nav">Nav<br>(200px)</nav>
            <main class="ex-sec1-main">Main Content<br>(1fr・残りをすべて埋める)</main>
          </div>
          
          <footer class="ex-sec1-footer">Footer (auto)</footer>
        </div>
      </div>

      <div class="ex-sec1-code">
        /* 💡 縦方向の骨格(フッターを一番下に落とす) */<br>
        <span class="ex-hl-blue">.layout-wrapper</span> {<br>
          <span class="ex-hl-green">display: grid;</span><br>
          <span class="ex-hl-red">min-height: 100vh;</span> /* 画面の高さを確保 */<br>
          <span class="ex-hl-comment">/* ヘッダー:中身次第、 メイン:残り全部、 フッター:中身次第 */</span><br>
          <span class="ex-hl-red">grid-template-rows: auto 1fr auto;</span><br>
        }<br><br>

        /* 💡 真ん中のエリア(サイドバーとメイン)を横並びに */<br>
        <span class="ex-hl-blue">.middle-area</span> {<br>
          <span class="ex-hl-green">display: grid;</span><br>
          <span class="ex-hl-green">grid-template-columns: 200px 1fr;</span> /* サイドは固定、メインは可変 */<br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.ex-sec1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.ex-sec1-demo-area {
  display: flex;
  justify-content: center;
}

.ex-sec1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.ex-sec1-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.ex-sec1-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

/* 💡 レイアウトのコンテナ(縦の分割) */
.ex-sec1-layout {
  display: grid;
  /* デモ用に高さを固定していますが、実務では min-height: 100vh; を使います */
  height: 300px; 
  grid-template-rows: auto 1fr auto;
  border: 2px solid #ced4da;
  border-radius: 4px;
  overflow: hidden;
}

.ex-sec1-header {
  background-color: #343a40;
  color: #fff;
  padding: 15px;
  text-align: center;
  font-weight: bold;
}

/* 💡 真ん中のエリア(横の分割) */
.ex-sec1-middle {
  display: grid;
  grid-template-columns: 120px 1fr; /* デモ用にサイドバーは120px */
}

.ex-sec1-nav {
  background-color: #6c757d;
  color: #fff;
  padding: 15px;
  font-size: 12px;
  text-align: center;
}

.ex-sec1-main {
  background-color: #fff;
  padding: 20px;
  font-weight: bold;
  color: #333;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ex-sec1-footer {
  background-color: #0d6efd;
  color: #fff;
  padding: 10px;
  text-align: center;
  font-size: 12px;
}

.ex-sec1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}

.ex-hl-green { color: #98c379; font-weight: bold; }
.ex-hl-blue { color: #61afef; font-weight: bold; }
.ex-hl-red { color: #e06c75; font-weight: bold; }
.ex-hl-comment { color: #6c757d; font-style: italic; }

タイル状の画像ギャラリーとカードレイアウト

大小様々なサイズの要素をパズルのように敷き詰めるgrid画像ギャラリー、近年のApple製品のサイトなどで見られる弁当箱UIと呼ばれるレイアウトです。

Gridで画像ギャラリーを作る場合は、画像(<img>)に対してwidth: 100%; height: 100%; object-fit: cover;をセットで指定してください。

これにより、画像が比率を保ったままマス目いっぱいにトリミングされて表示されます。

🍱 弁当箱(Bento)UI・モザイクギャラリー
/* 💡 ギャラリーのベース(3列のグリッド) */
.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 15px;
}

/* 💡 A:縦横に2マスずつ伸びる目玉コンテンツ */
.item-large {
  grid-column: span 2; /* 横に2マス結合 */
  grid-row: span 2; /* 縦に2マス結合 */
}

/* 💡 D:横に2マス伸びるバナー的コンテンツ */
.item-wide {
  grid-column: span 2; /* 横に2マス結合 */
}
HTMLコード表示
<div class="ex-sec2-wrapper">
  <div class="ex-sec2-demo-area">
    <div class="ex-sec2-box">
      <div class="ex-sec2-label">🍱 弁当箱(Bento)UI・モザイクギャラリー</div>
      
      <div class="ex-sec2-visual">
        <div class="ex-sec2-gallery">
          <div class="ex-sec2-item ex-sec2-large">A (2x2)</div>
          <div class="ex-sec2-item">B</div>
          <div class="ex-sec2-item">C</div>
          <div class="ex-sec2-item ex-sec2-wide">D (横長)</div>
          <div class="ex-sec2-item">E</div>
        </div>
      </div>

      <div class="ex-sec1-code">
        /* 💡 ギャラリーのベース(3列のグリッド) */<br>
        <span class="ex-hl-blue">.gallery</span> {<br>
          <span class="ex-hl-green">display: grid;</span><br>
          <span class="ex-hl-green">grid-template-columns: repeat(3, 1fr);</span><br>
          <span class="ex-hl-green">gap: 15px;</span><br>
        }<br><br>

        /* 💡 A:縦横に2マスずつ伸びる目玉コンテンツ */<br>
        <span class="ex-hl-blue">.item-large</span> {<br>
          <span class="ex-hl-red">grid-column: span 2;</span> /* 横に2マス結合 */<br>
          <span class="ex-hl-red">grid-row: span 2;</span>    /* 縦に2マス結合 */<br>
        }<br><br>

        /* 💡 D:横に2マス伸びるバナー的コンテンツ */<br>
        <span class="ex-hl-blue">.item-wide</span> {<br>
          <span class="ex-hl-red">grid-column: span 2;</span> /* 横に2マス結合 */<br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.ex-sec2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.ex-sec2-demo-area {
  display: flex;
  justify-content: center;
}

.ex-sec2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.ex-sec2-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.ex-sec2-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

/* 💡 ギャラリーのコンテナ */
.ex-sec2-gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* 各行の高さを固定して綺麗なタイル状にする */
  grid-auto-rows: 80px; 
  gap: 10px;
}

.ex-sec2-item {
  background-color: #198754;
  color: #fff;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  font-size: 14px;
  /* 写真を入れる場合を想定した装飾 */
  background-image: linear-gradient(135deg, #20c997 0%, #198754 100%);
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}

/* 💡 個別の結合設定 */
.ex-sec2-large {
  grid-column: span 2;
  grid-row: span 2;
}

.ex-sec2-wide {
  grid-column: span 2;
}

Masonry(Pinterest風)や複雑なグリッド

画像やカードの高さがバラバラでも、隙間なく上に詰めて配置していくレイアウトを「grid masonry(またはgrid pinterest/grid 瀑布流)」と呼びます。

また、管理画面などで様々なウィジェットを配置するgridダッシュボードレイアウトもGridの真骨頂です。

実務でPinterest風のMasonryレイアウトを作る場合は、GridではなくCSSのカラムレイアウト(column-count)を使うか、Masonry.jsなどのJavaScriptライブラリを使用するのがよいです。

一方、ダッシュボードのような「複雑だがマスのルールは決まっている」レイアウトであれば、前述のgrid-template-areasspanを駆使して構築できます。

📊 複雑なダッシュボードレイアウト

※大小のパネルをパズルのように配置した、管理画面風のレイアウトです。

グラフ・チャート (広)
数値
サマリー
最新
ニュース
ユーザーリスト (長)
/* 💡 4列×3行の細かいグリッドベースを作る */
.dashboard {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 60px; /* 行のベース高さを決める */
  gap: 15px;
}

/* 💡 グラフは横に3マス、縦に2マス使う */
.panel-chart {
  grid-column: span 3;
  grid-row: span 2;
}

/* 💡 リストは横に3マス、縦に1マス使う */
.panel-list {
  grid-column: span 3;
  grid-row: span 1;
}
HTMLコード表示
<div class="ex-sec3-wrapper">
  <div class="ex-sec3-demo-area">
    <div class="ex-sec3-box">
      <div class="ex-sec3-label">📊 複雑なダッシュボードレイアウト</div>
      
      <div class="ex-sec3-visual">
        <p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
          ※大小のパネルをパズルのように配置した、管理画面風のレイアウトです。
        </p>

        <div class="ex-sec3-dashboard">
          <div class="ex-sec3-panel ex-sec3-chart">グラフ・チャート (広)</div>
          <div class="ex-sec3-panel ex-sec3-stats">数値<br>サマリー</div>
          <div class="ex-sec3-panel ex-sec3-news">最新<br>ニュース</div>
          <div class="ex-sec3-panel ex-sec3-list">ユーザーリスト (長)</div>
        </div>
      </div>

      <div class="ex-sec1-code">
        /* 💡 4列×3行の細かいグリッドベースを作る */<br>
        <span class="ex-hl-blue">.dashboard</span> {<br>
          <span class="ex-hl-green">display: grid;</span><br>
          <span class="ex-hl-green">grid-template-columns: repeat(4, 1fr);</span><br>
          <span class="ex-hl-green">grid-auto-rows: 60px;</span> /* 行のベース高さを決める */<br>
          <span class="ex-hl-green">gap: 15px;</span><br>
        }<br><br>

        /* 💡 グラフは横に3マス、縦に2マス使う */<br>
        <span class="ex-hl-blue">.panel-chart</span> {<br>
          <span class="ex-hl-red">grid-column: span 3;</span><br>
          <span class="ex-hl-red">grid-row: span 2;</span><br>
        }<br><br>

        /* 💡 リストは横に3マス、縦に1マス使う */<br>
        <span class="ex-hl-blue">.panel-list</span> {<br>
          <span class="ex-hl-red">grid-column: span 3;</span><br>
          <span class="ex-hl-red">grid-row: span 1;</span><br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.ex-sec3-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.ex-sec3-demo-area {
  display: flex;
  justify-content: center;
}

.ex-sec3-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.ex-sec3-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.ex-sec3-visual {
  background-color: #212529; /* ダッシュボードっぽくダーク背景に */
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
}

/* 💡 ダッシュボードのコンテナ */
.ex-sec3-dashboard {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 60px;
  gap: 15px;
}

.ex-sec3-panel {
  background-color: #343a40;
  color: #f8f9fa;
  border: 1px solid #495057;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: bold;
  text-align: center;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
}

/* 個別のサイズ設定 */
.ex-sec3-chart {
  grid-column: span 3;
  grid-row: span 2;
  background-color: #052c65; /* 少し色を変える */
  border-color: #0a58ca;
}

.ex-sec3-stats {
  grid-column: span 1;
  grid-row: span 1;
}

.ex-sec3-news {
  grid-column: span 1;
  grid-row: span 2;
}

.ex-sec3-list {
  grid-column: span 3;
  grid-row: span 1;
}

Gridのトラブル解決

Gridは便利ですが、独特の仕様による予期せぬレイアウト崩れに遭遇することがあります。

また、複雑なGridを手書きするのが難しい場合は、直感的にコードを生成できるGridジェネレーターなどのツールを活用するのも実務では一般的です。

ここでは、実務で頻出する画像のはみ出しや意図しない高さの伸びといったトラブルの解決策を解説します。

Gridのトラブル解決
  • 画像がはみ出る・レスポンシブが崩れる時の対策
  • 高さが揃わない・縦に伸びる時の解決策

画像がはみ出る・レスポンシブが崩れる時の対策

Gridレイアウトの中で多いトラブルがgridから画像がはみ出るという問題です。

特に、解像度の大きな画像をグリッドアイテム内に入れた際、画像がはみ出る現象が起き、レイアウト全体が横に広がって横スクロールが発生するミスが頻発します。

画像の飛び出しを防ぐには、画像タグに対するmax-width: 100%;に加えて、Gridの列指定にminmax(0, 1fr)を使用します。

最小値を0にすることで、中身の画像が大きくてもマス目が画面幅を突き破って広がるのを防ぎます。

🖼 画像のはみ出し(overflow)対策

※「1fr」だけだと巨大な画像に押し広げられますが、「minmax(0, 1fr)」を使うと枠内に収まります。

❌ 失敗:1fr指定(画像がはみ出る)

800pxの巨大な画像
テキスト

⭕️ 正解:minmax(0, 1fr)指定(画像が収まる)

800pxの巨大な画像
テキスト
/* ❌ 1frのままだと画像幅でマスが広がる */
.grid-wrong {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

/* ⭕️ 最小値を0に指定してはみ出しを防ぐ */
.grid-correct {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

/* 💡 画像自体のレスポンシブ対応も必須 */
img {
  max-width: 100%;
  height: auto;
}
HTMLコード表示
<div class="trb-sec1-wrapper">
  <div class="trb-sec1-demo-area">
    <div class="trb-sec1-box">
      <div class="trb-sec1-label">🖼 画像のはみ出し(overflow)対策</div>
      
      <div class="trb-sec1-visual">
        <p style="font-size:12px; color:#555; margin-bottom:15px; text-align:center;">
          ※「1fr」だけだと巨大な画像に押し広げられますが、「minmax(0, 1fr)」を使うと枠内に収まります。
        </p>

        <div style="margin-bottom: 20px;">
          <p style="font-size:13px; font-weight:bold; color:#dc3545; margin:0 0 5px 0;">❌ 失敗:1fr指定(画像がはみ出る)</p>
          <div class="trb-sec1-grid-wrong">
            <div class="trb-sec1-item">
              <div class="trb-sec1-fake-img-large">800pxの巨大な画像</div>
            </div>
            <div class="trb-sec1-item">テキスト</div>
          </div>
        </div>

        <div>
          <p style="font-size:13px; font-weight:bold; color:#198754; margin:0 0 5px 0;">⭕️ 正解:minmax(0, 1fr)指定(画像が収まる)</p>
          <div class="trb-sec1-grid-correct">
            <div class="trb-sec1-item">
              <div class="trb-sec1-fake-img-large">800pxの巨大な画像</div>
            </div>
            <div class="trb-sec1-item">テキスト</div>
          </div>
        </div>
      </div>

      <div class="trb-sec1-code">
        /* ❌ 1frのままだと画像幅でマスが広がる */<br>
        <span class="trb-hl-blue">.grid-wrong</span> {<br>
          <span class="trb-hl-green">display: grid;</span><br>
          <span class="trb-hl-red">grid-template-columns: 1fr 1fr;</span><br>
        }<br><br>

        /* ⭕️ 最小値を0に指定してはみ出しを防ぐ */<br>
        <span class="trb-hl-blue">.grid-correct</span> {<br>
          <span class="trb-hl-green">display: grid;</span><br>
          <span class="trb-hl-red">grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);</span><br>
        }<br><br>

        /* 💡 画像自体のレスポンシブ対応も必須 */<br>
        <span class="trb-hl-blue">img</span> {<br>
          <span class="trb-hl-green">max-width: 100%;</span><br>
          <span class="trb-hl-green">height: auto;</span><br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.trb-sec1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.trb-sec1-demo-area {
  display: flex;
  justify-content: center;
}

.trb-sec1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.trb-sec1-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.trb-sec1-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
  /* 親枠からはみ出す挙動を視覚化するため */
  overflow: hidden; 
}

/* ❌ 失敗のGrid */
.trb-sec1-grid-wrong {
  display: grid;
  /* 1frだと中身が巨大な場合に押し広げられる */
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  border: 2px solid #dc3545;
  background-color: #fff;
  padding: 5px;
}

/* ⭕️ 成功のGrid */
.trb-sec1-grid-correct {
  display: grid;
  /* 最小値を0にして枠内に抑え込む */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 10px;
  border: 2px solid #198754;
  background-color: #fff;
  padding: 5px;
}

.trb-sec1-item {
  background-color: #e9ecef;
  padding: 10px;
  font-weight: bold;
  font-size: 12px;
  text-align: center;
}

/* 巨大な画像を擬似的に表現 */
.trb-sec1-fake-img-large {
  background-color: #0d6efd;
  color: #fff;
  width: 800px; /* 親枠より明らかに大きい固定幅 */
  padding: 20px 0;
  max-width: 100%; /* これがないと画像が飛び出す */
}

.trb-sec1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}

.trb-hl-green { color: #98c379; font-weight: bold; }
.trb-hl-blue { color: #61afef; font-weight: bold; }
.trb-hl-red { color: #e06c75; font-weight: bold; }

高さが揃わない・縦に伸びる時の解決策

Gridの便利な仕様として、同じ行にあるアイテムは中身の量が違っても自動的に同じ高さに揃うというものがあります。

これはalign-items: stretch;という値がデフォルトで効いているためです。

アイテムが勝手に縦に伸びるのを防ぐには、親要素のGridコンテナにalign-items: start;を指定します。

これにより、各アイテムは「中身のコンテンツの高さ」に合わせて上詰めで配置され、不自然な間延びを防ぎます。

また、特定のアイテムだけを伸ばしたくない場合は、子要素に対してalign-self: start;を指定することも可能です。

↕️ 意図しない「縦伸び」を防ぐ(align-items)

❌ 失敗:デフォルト(stretch)だとボタンが間延びする

テキスト量が多いため、
このカードの高さが
全体の基準になります。

⭕️ 正解:align-items: start で伸びを防ぐ

テキスト量が多いため、
このカードの高さが
全体の基準になります。
/* ❌ デフォルトだと隣に合わせて縦に伸びる */
.grid-container {
  display: grid;
  grid-template-columns: 1fr auto;
  /* align-items: stretch; が隠れている */
}

/* ⭕️ start を指定して本来の高さに上詰めする */
.grid-container-start {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: start; /* 💡 縦の伸びを解除する */
}
HTMLコード表示
<div class="trb-sec2-wrapper">
  <div class="trb-sec2-demo-area">
    <div class="trb-sec2-box">
      <div class="trb-sec2-label">↕️ 意図しない「縦伸び」を防ぐ(align-items)</div>
      
      <div class="trb-sec2-visual">
        <div style="margin-bottom: 25px;">
          <p style="font-size:13px; font-weight:bold; color:#dc3545; margin:0 0 5px 0;">❌ 失敗:デフォルト(stretch)だとボタンが間延びする</p>
          <div class="trb-sec2-grid-stretch">
            <div class="trb-sec2-text-card">
              テキスト量が多いため、<br>
              このカードの高さが<br>
              全体の基準になります。
            </div>
            <button class="trb-sec2-btn">送信ボタン</button>
          </div>
        </div>

        <div>
          <p style="font-size:13px; font-weight:bold; color:#198754; margin:0 0 5px 0;">⭕️ 正解:align-items: start で伸びを防ぐ</p>
          <div class="trb-sec2-grid-start">
            <div class="trb-sec2-text-card">
              テキスト量が多いため、<br>
              このカードの高さが<br>
              全体の基準になります。
            </div>
            <button class="trb-sec2-btn">送信ボタン</button>
          </div>
        </div>
      </div>

      <div class="trb-sec1-code">
        /* ❌ デフォルトだと隣に合わせて縦に伸びる */<br>
        <span class="trb-hl-blue">.grid-container</span> {<br>
          <span class="trb-hl-green">display: grid;</span><br>
          <span class="trb-hl-green">grid-template-columns: 1fr auto;</span><br>
          <span class="trb-hl-red">/* align-items: stretch; が隠れている */</span><br>
        }<br><br>

        /* ⭕️ start を指定して本来の高さに上詰めする */<br>
        <span class="trb-hl-blue">.grid-container-start</span> {<br>
          <span class="trb-hl-green">display: grid;</span><br>
          <span class="trb-hl-green">grid-template-columns: 1fr auto;</span><br>
          <span class="trb-hl-red">align-items: start;</span> /* 💡 縦の伸びを解除する */<br>
        }
      </div>
    </div>
  </div>
</div>
CSSコード表示
.trb-sec2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}

.trb-sec2-demo-area {
  display: flex;
  justify-content: center;
}

.trb-sec2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 600px;
  border-radius: 4px;
}

.trb-sec2-label {
  font-size: 15px;
  font-weight: bold;
  margin-bottom: 20px;
  color: #333;
}

.trb-sec2-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

/* ❌ 失敗のGrid(デフォルトのstretch) */
.trb-sec2-grid-stretch {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 15px;
  background-color: #fff;
  padding: 10px;
  border: 1px solid #ced4da;
}

/* ⭕️ 成功のGrid(start) */
.trb-sec2-grid-start {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 15px;
  /* 💡 ここで縦伸びを防ぐ */
  align-items: start;
  background-color: #fff;
  padding: 10px;
  border: 1px solid #ced4da;
}

.trb-sec2-text-card {
  background-color: #e9ecef;
  padding: 15px;
  font-size: 13px;
  color: #333;
  border-radius: 4px;
}

.trb-sec2-btn {
  background-color: #0d6efd;
  color: #fff;
  border: none;
  padding: 10px 20px;
  font-weight: bold;
  border-radius: 4px;
  cursor: pointer;
}

まとめ

分かりやすいようにまとめを記載します。

本記事のまとめ
  • Gridは縦(行)と横(列)を制御する2次元レイアウト手法である。
  • ページの大枠はGrid、部品の配置はFlexboxで使い分ける。
  • 親要素にdisplay: grid;を指定し、grid-template-columnsrowsでマス目を作る。
  • fr単位を使えば、画面幅に応じた比率レイアウトが実現できる。
  • アイテム間の隙間は、marginではなくgapプロパティを使用する。
  • grid-template-areasを使えば、直感的な名前付けで要素を結合・配置できる。
  • place-items: center;を指定することで、上下左右の中央寄せが1行で完結する。
  • repeat(auto-fit, minmax(最小幅, 1fr))により、メディアクエリ不要のレスポンシブが実装できる。
  • 画像が枠を押し広げてはみ出す場合は、列幅にminmax(0, 1fr)を指定して防ぐ。
  • アイテムが隣に合わせて縦伸びする場合は、親要素にalign-items: start;を指定する。

よくある質問(FAQ)

GridとFlexboxの違いは何ですか?

大きな違いは、制御できる方向です。

Flexboxは「1次元(横一列、または縦一列)」のレイアウトを得意とし、ナビゲーションメニューやアイコンの横並びなど、要素内の細かな配置に適しています。

Gridは「2次元(縦と横のマス目)」を同時に制御でき、ページ全体の大枠や、カードを敷き詰めるギャラリー画面などの大きな配置に適しています。

実務では「外枠はGridで作り、その中の部品はFlexboxで並べる」という組み合わせがベストプラクティスです。

Gridで要素を上下左右の中央寄せにするには?

親要素に対してdisplay: grid;place-items: center;の2行を記述するだけで、中のアイテムが中央配置されます。

これはjustify-items: center;(横方向の中央)と align-items: center;(縦方向の中央)を1行で指定できるショートハンド(一括指定)です。

従来のposition: absolute;transformを使った複雑な中央寄せを簡単に記述する手法です。

Gridは古いブラウザでも正しく表示されますか?

はい、Chrome、Safari、Edge、Firefoxなどの主要なモダンブラウザ(スマホ含む)ではサポートされており、安心して使用できます。
Internet Explorer(IE11)では一部独自の古い仕様で動くためレイアウト崩れが起きる可能性がありましたが、Microsoft社によるIEの公式サポートは完全に終了しています。

Web制作において、IEを気にしてGridの使用を控える必要は全くありません。

メディアクエリを使わずにレスポンシブにする書き方を教えてください。

列の指定にrepeat(auto-fit, minmax(最小幅, 1fr))を使用します。

例えばgrid-template-columns: repeat(auto-fit, minmax(300px, 1fr));と指定すると、「アイテムの幅を最低300pxに保ちつつ、画面が広がれば自動で列を増やし、画面が縮めば自動で列を減らして折り返す」というレスポンシブ挙動がメディアクエリを書かずに実現できます。

Gridのauto-fitとauto-fillの違いがわかりません。

どちらも画面幅に合わせて自動で列を折り返す機能ですが、画面にスペースが余った時の挙動が異なります。

auto-fillは、スペースが余ると見えない空のマス目を作って埋めようとするため、アイテム数が少ないと右側に大きな余白ができます。

一方、auto-fitは空のマス目を作らず、存在するアイテムの幅を引き伸ばして画面いっぱいにフィットさせます。

カード一覧などで敷き詰めたい場合は、基本的にauto-fitを使用します。

この記事を書いた人

sugiのアバター sugi Site operator

【経歴】玉川大学工学部卒業→新卒SIer企業入社→2年半後に独立→プログラミングスクール運営/受託案件→フリーランスエンジニア&SEOコンサル→Python特化のコンテンツサイトJob Code&UIコピペサイトCode Stock運営中

目次