はじめに

CSS Gridの基本概念やアイテム配置を学んだ後、「実際のWebサイトではどのように活用するのか」という疑問を持つ方は多いでしょう。CSS Gridは二次元レイアウトを得意とするため、ページ全体の構成からUIコンポーネントの内部配置まで、幅広い場面で威力を発揮します。

本記事では、CSS Gridを使った実践的なレイアウトパターンを解説します。

  • ページレイアウト(ヘッダー・サイドバー・メイン・フッター)
  • 画像ギャラリー(レスポンシブ対応・マソンリー風)
  • ダッシュボードUI(複数ウィジェットの二次元配置)
  • auto-fillauto-fitの違いと使い分け

これらのパターンを習得することで、複雑なページ構成を効率的に実装できるようになります。

前提条件

本記事を読み進めるにあたり、以下の知識があることを前提としています。

  • CSS Gridの基本概念(グリッドコンテナ、グリッドアイテム、グリッドライン)
  • grid-template-columnsgrid-template-rowsによるトラック定義
  • grid-columngrid-rowgrid-areaによるアイテム配置
  • frユニットとrepeat()関数の基本的な使い方

これらの基礎知識については、以下の記事で解説しています。

  • CSS Grid入門 - グリッドレイアウトの基本概念を理解する
  • CSS Gridのアイテム配置 - grid-column・grid-row・grid-areaの使い方

動作確認環境

  • Google Chrome 131以降
  • Firefox 133以降
  • Safari 18以降
  • Microsoft Edge 131以降

パターン1: ページレイアウト

Webサイトの典型的なページ構成である「ヘッダー・サイドバー・メインコンテンツ・フッター」の配置は、CSS Gridで最も効率的に実現できるパターンの一つです。

パターン1-1: 基本的なホーリーグレイルレイアウト

「ホーリーグレイル(Holy Grail)レイアウト」と呼ばれる、ヘッダー・フッターが全幅、サイドバーとメインコンテンツが中央に配置される構成です。

graph TB
    subgraph layout["ホーリーグレイルレイアウト"]
        header["ヘッダー(全幅)"]
        subgraph middle["中央エリア"]
            sidebar["サイドバー"]
            main["メインコンテンツ"]
        end
        footer["フッター(全幅)"]
    end
1
2
3
4
5
6
<div class="page-layout">
  <header class="header">ヘッダー</header>
  <aside class="sidebar">サイドバー</aside>
  <main class="main">メインコンテンツ</main>
  <footer class="footer">フッター</footer>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
.page-layout {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  min-height: 100vh;
}

.header {
  grid-area: header;
  background-color: #1a1a2e;
  color: #ffffff;
  padding: 1rem 2rem;
}

.sidebar {
  grid-area: sidebar;
  background-color: #16213e;
  color: #ffffff;
  padding: 1rem;
}

.main {
  grid-area: main;
  background-color: #f5f5f5;
  padding: 2rem;
}

.footer {
  grid-area: footer;
  background-color: #1a1a2e;
  color: #ffffff;
  padding: 1rem 2rem;
  text-align: center;
}

grid-template-areasを使用することで、HTMLの記述順序に関係なく、視覚的にレイアウトを定義できます。各エリア名は直感的に理解できるため、コードの可読性が大幅に向上します。

パターン1-2: レスポンシブ対応ページレイアウト

モバイル端末では1カラム、デスクトップでは2カラムに切り替わるレスポンシブ対応のレイアウトです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.page-layout-responsive {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto auto 1fr auto;
  grid-template-areas:
    "header"
    "sidebar"
    "main"
    "footer";
  min-height: 100vh;
}

@media (min-width: 768px) {
  .page-layout-responsive {
    grid-template-columns: 250px 1fr;
    grid-template-rows: auto 1fr auto;
    grid-template-areas:
      "header header"
      "sidebar main"
      "footer footer";
  }
}

@media (min-width: 1200px) {
  .page-layout-responsive {
    grid-template-columns: 280px 1fr 280px;
    grid-template-areas:
      "header header header"
      "sidebar main aside"
      "footer footer footer";
  }
}

メディアクエリと組み合わせることで、画面サイズに応じてグリッド構造を柔軟に変更できます。grid-template-areasの値を変更するだけで、レイアウトを完全に再構成できる点がCSS Gridの強みです。

パターン1-3: フルスクリーンアプリケーションレイアウト

SPAやダッシュボードでよく使われる、ビューポート全体を占めるレイアウトです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<div class="app-layout">
  <header class="app-header">
    <h1>アプリケーション名</h1>
    <nav class="app-nav">ナビゲーション</nav>
  </header>
  <aside class="app-sidebar">サイドメニュー</aside>
  <main class="app-main">
    <div class="app-content">コンテンツエリア</div>
  </main>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
.app-layout {
  display: grid;
  grid-template-columns: 60px 1fr;
  grid-template-rows: 60px 1fr;
  grid-template-areas:
    "header header"
    "sidebar main";
  height: 100vh;
  overflow: hidden;
}

.app-header {
  grid-area: header;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #1a1a2e;
  color: #ffffff;
  padding: 0 2rem;
  border-bottom: 1px solid #2d2d44;
}

.app-sidebar {
  grid-area: sidebar;
  background-color: #16213e;
  color: #ffffff;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 1rem;
}

.app-main {
  grid-area: main;
  overflow-y: auto;
  background-color: #f0f2f5;
}

.app-content {
  padding: 2rem;
  max-width: 1200px;
  margin: 0 auto;
}

height: 100vhoverflow: hiddenの組み合わせにより、グリッド全体がビューポートに固定されます。メインコンテンツエリアのみがoverflow-y: autoでスクロール可能となり、アプリケーションらしい操作感を実現できます。

パターン1-4: サイドバー開閉対応レイアウト

サイドバーの表示・非表示を切り替えられるレイアウトです。CSS変数を活用することで、JavaScriptからの制御が容易になります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
:root {
  --sidebar-width: 250px;
}

.layout-collapsible {
  display: grid;
  grid-template-columns: var(--sidebar-width) 1fr;
  grid-template-rows: 60px 1fr;
  grid-template-areas:
    "header header"
    "sidebar main";
  height: 100vh;
  transition: grid-template-columns 0.3s ease;
}

.layout-collapsible.sidebar-collapsed {
  --sidebar-width: 60px;
}

.sidebar-collapsible {
  grid-area: sidebar;
  background-color: #16213e;
  overflow: hidden;
  white-space: nowrap;
}

.sidebar-collapsible .nav-text {
  opacity: 1;
  transition: opacity 0.3s ease;
}

.layout-collapsible.sidebar-collapsed .nav-text {
  opacity: 0;
}

CSS変数--sidebar-widthを切り替えることで、サイドバーの幅をスムーズにアニメーションさせながら変更できます。grid-template-columnsにトランジションを適用することで、レイアウトの変化がなめらかになります。

パターン2: 画像ギャラリー

画像ギャラリーはCSS Gridの得意分野の一つです。repeat()auto-fillauto-fitを組み合わせることで、レスポンシブで柔軟なギャラリーを実現できます。

パターン2-1: 基本的なグリッドギャラリー

固定列数のシンプルなギャラリーです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<div class="gallery-basic">
  <figure class="gallery-item">
    <img src="/images/photo1.jpg" alt="写真1">
    <figcaption>キャプション1</figcaption>
  </figure>
  <figure class="gallery-item">
    <img src="/images/photo2.jpg" alt="写真2">
    <figcaption>キャプション2</figcaption>
  </figure>
  <figure class="gallery-item">
    <img src="/images/photo3.jpg" alt="写真3">
    <figcaption>キャプション3</figcaption>
  </figure>
  <figure class="gallery-item">
    <img src="/images/photo4.jpg" alt="写真4">
    <figcaption>キャプション4</figcaption>
  </figure>
  <figure class="gallery-item">
    <img src="/images/photo5.jpg" alt="写真5">
    <figcaption>キャプション5</figcaption>
  </figure>
  <figure class="gallery-item">
    <img src="/images/photo6.jpg" alt="写真6">
    <figcaption>キャプション6</figcaption>
  </figure>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.gallery-basic {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  padding: 1rem;
}

.gallery-item {
  margin: 0;
  background-color: #ffffff;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.gallery-item img {
  width: 100%;
  height: 200px;
  object-fit: cover;
  display: block;
}

.gallery-item figcaption {
  padding: 0.75rem 1rem;
  font-size: 0.875rem;
  color: #666666;
}

repeat(3, 1fr)で3列の等幅グリッドを作成しています。object-fit: coverを使用することで、アスペクト比が異なる画像も統一した見た目で表示できます。

パターン2-2: auto-fillを使ったレスポンシブギャラリー

画面幅に応じて自動的に列数が変化するギャラリーです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
.gallery-auto-fill {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.5rem;
  padding: 1.5rem;
}

.gallery-auto-fill .gallery-item {
  margin: 0;
  background-color: #ffffff;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.gallery-auto-fill .gallery-item:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}

auto-fillは「できるだけ多くの列を埋める」という動作をします。minmax(280px, 1fr)と組み合わせることで、各列は最小280px、最大で利用可能なスペースを均等に分配する動作となります。

auto-fillとauto-fitの違い

auto-fillauto-fitは似ていますが、アイテム数が少ない場合に挙動が異なります。

flowchart LR
    subgraph container["コンテナ幅: 1000px / アイテム: 2個"]
        subgraph autofill["auto-fill"]
            A1["アイテム"] --> B1["アイテム"] --> C1["空トラック"] --> D1["空トラック"]
        end
        subgraph autofit["auto-fit"]
            A2["アイテム(拡張)"] --> B2["アイテム(拡張)"]
        end
    end
キーワード アイテムが少ない場合の挙動 使用場面
auto-fill 空のトラックを維持する グリッドの一貫性を保ちたい場合
auto-fit 空のトラックを0幅に折りたたむ アイテムを広げて埋めたい場合
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
/* auto-fill: 空トラックが残る */
.gallery-auto-fill-example {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1rem;
}

/* auto-fit: アイテムが伸びて空間を埋める */
.gallery-auto-fit-example {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
}

アイテム数が多い場合は両者の動作は同じですが、アイテム数が少ない場合に違いが現れます。一般的に、アイテムを広げて表示したい場合はauto-fit、一定のグリッド構造を維持したい場合はauto-fillを使用します。

パターン2-3: フィーチャー画像付きギャラリー

最初の画像を大きく表示する、雑誌風のレイアウトです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<div class="gallery-featured">
  <figure class="gallery-item featured">
    <img src="/images/featured.jpg" alt="フィーチャー画像">
    <figcaption>フィーチャー記事</figcaption>
  </figure>
  <figure class="gallery-item">
    <img src="/images/photo1.jpg" alt="写真1">
  </figure>
  <figure class="gallery-item">
    <img src="/images/photo2.jpg" alt="写真2">
  </figure>
  <figure class="gallery-item">
    <img src="/images/photo3.jpg" alt="写真3">
  </figure>
  <figure class="gallery-item">
    <img src="/images/photo4.jpg" alt="写真4">
  </figure>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
.gallery-featured {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(2, 250px);
  gap: 1rem;
  padding: 1rem;
}

.gallery-featured .featured {
  grid-column: 1 / 3;
  grid-row: 1 / 3;
}

.gallery-featured .gallery-item {
  margin: 0;
  position: relative;
  overflow: hidden;
  border-radius: 8px;
}

.gallery-featured .gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.gallery-featured .gallery-item figcaption {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 1rem;
  background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
  color: #ffffff;
}

.featuredクラスを持つ要素がgrid-column: 1 / 3grid-row: 1 / 3により2列×2行の領域を占有します。これにより、最初の画像が他の4倍のサイズで表示されます。

パターン2-4: マソンリー風レイアウト

Pinterestのような高さが異なるアイテムを配置するレイアウトです。CSS Gridのgrid-row: spanを活用します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
.gallery-masonry {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  grid-auto-rows: 10px;
  gap: 1rem;
  padding: 1rem;
}

.gallery-masonry .gallery-item {
  margin: 0;
  border-radius: 8px;
  overflow: hidden;
}

.gallery-masonry .gallery-item.small {
  grid-row: span 20;
}

.gallery-masonry .gallery-item.medium {
  grid-row: span 30;
}

.gallery-masonry .gallery-item.large {
  grid-row: span 40;
}

.gallery-masonry .gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

grid-auto-rows: 10pxで細かいグリッド行を作成し、各アイテムがgrid-row: spanで複数行にまたがることで高さの異なるレイアウトを実現します。

パターン3: ダッシュボードUI

ダッシュボードは複数のウィジェットを二次元に配置する典型的なユースケースです。CSS Gridは、サイズの異なるウィジェットを柔軟に配置できます。

パターン3-1: 基本的なダッシュボードグリッド

統計カード、グラフ、テーブルなどを配置するダッシュボードです。

1
2
3
4
5
6
7
8
9
<div class="dashboard">
  <div class="widget widget-stats">売上統計</div>
  <div class="widget widget-stats">訪問者数</div>
  <div class="widget widget-stats">コンバージョン率</div>
  <div class="widget widget-stats">平均注文額</div>
  <div class="widget widget-chart">売上グラフ</div>
  <div class="widget widget-table">最新注文一覧</div>
  <div class="widget widget-activity">アクティビティログ</div>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
.dashboard {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: auto auto 1fr;
  gap: 1.5rem;
  padding: 1.5rem;
  min-height: 100vh;
  background-color: #f0f2f5;
}

.widget {
  background-color: #ffffff;
  border-radius: 12px;
  padding: 1.5rem;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.widget-stats {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.widget-chart {
  grid-column: span 3;
  min-height: 300px;
}

.widget-table {
  grid-column: span 3;
  grid-row: span 2;
}

.widget-activity {
  grid-column: span 1;
}

ウィジェットごとにgrid-column: spangrid-row: spanを使い分けることで、それぞれのコンテンツに適したサイズを割り当てられます。

パターン3-2: 名前付きエリアを使ったダッシュボード

grid-template-areasを使用することで、ダッシュボードのレイアウトをより直感的に定義できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
.dashboard-named {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: auto 300px 1fr;
  grid-template-areas:
    "stat1 stat2 stat3 stat4"
    "chart chart chart activity"
    "table table table activity";
  gap: 1.5rem;
  padding: 1.5rem;
  min-height: 100vh;
  background-color: #f0f2f5;
}

.widget-stat1 { grid-area: stat1; }
.widget-stat2 { grid-area: stat2; }
.widget-stat3 { grid-area: stat3; }
.widget-stat4 { grid-area: stat4; }
.widget-chart { grid-area: chart; }
.widget-table { grid-area: table; }
.widget-activity { grid-area: activity; }

grid-template-areasはASCIIアートのようにレイアウトを視覚化できるため、複雑なダッシュボードでも全体像を把握しやすくなります。

パターン3-3: レスポンシブダッシュボード

画面サイズに応じてレイアウトを変更するダッシュボードです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
.dashboard-responsive {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  padding: 1rem;
}

.dashboard-responsive .widget {
  background-color: #ffffff;
  border-radius: 12px;
  padding: 1.5rem;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

@media (min-width: 640px) {
  .dashboard-responsive {
    grid-template-columns: repeat(2, 1fr);
  }

  .dashboard-responsive .widget-chart {
    grid-column: span 2;
  }
}

@media (min-width: 1024px) {
  .dashboard-responsive {
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: auto 300px 1fr;
    grid-template-areas:
      "stat1 stat2 stat3 stat4"
      "chart chart chart activity"
      "table table table activity";
  }
}

@media (min-width: 1440px) {
  .dashboard-responsive {
    grid-template-columns: 1fr repeat(4, minmax(200px, 1fr)) 1fr;
    grid-template-areas:
      ". stat1 stat2 stat3 stat4 ."
      ". chart chart chart activity ."
      ". table table table activity .";
    max-width: 1600px;
    margin: 0 auto;
  }
}

モバイルでは1カラム、タブレットでは2カラム、デスクトップでは4カラム、大画面では中央寄せという段階的なレイアウト変更を実現しています。grid-template-areas内のピリオド(.)は空のセルを意味し、左右に余白を作成できます。

パターン3-4: ドラッグ可能なダッシュボード用グリッド

ドラッグ&ドロップでウィジェットを並び替えられるダッシュボードの土台となるグリッド構造です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
.dashboard-draggable {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-auto-rows: 80px;
  gap: 1rem;
  padding: 1rem;
  min-height: 100vh;
}

.widget-draggable {
  background-color: #ffffff;
  border-radius: 12px;
  padding: 1rem;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  cursor: move;
  transition: box-shadow 0.2s ease;
}

.widget-draggable:hover {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
}

/* ウィジェットサイズのバリエーション */
.widget-1x1 {
  grid-column: span 3;
  grid-row: span 2;
}

.widget-2x1 {
  grid-column: span 6;
  grid-row: span 2;
}

.widget-2x2 {
  grid-column: span 6;
  grid-row: span 4;
}

.widget-4x2 {
  grid-column: span 12;
  grid-row: span 4;
}

12カラムグリッドは柔軟性が高く、BootstrapやTailwind CSSなどのフレームワークでも採用されている標準的な構成です。grid-auto-rowsで行の高さを固定することで、ドラッグ時の配置位置を予測しやすくなります。

パターン4: フォームレイアウト

フォームのラベルと入力欄の配置にもCSS Gridは有効です。

パターン4-1: ラベルと入力欄の2カラムレイアウト

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<form class="form-grid">
  <label for="name" class="form-label">お名前</label>
  <input type="text" id="name" class="form-input" placeholder="山田太郎">
  
  <label for="email" class="form-label">メールアドレス</label>
  <input type="email" id="email" class="form-input" placeholder="example@email.com">
  
  <label for="phone" class="form-label">電話番号</label>
  <input type="tel" id="phone" class="form-input" placeholder="090-1234-5678">
  
  <label for="message" class="form-label">お問い合わせ内容</label>
  <textarea id="message" class="form-input form-textarea" rows="5"></textarea>
  
  <div class="form-actions">
    <button type="submit" class="btn-submit">送信する</button>
  </div>
</form>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
.form-grid {
  display: grid;
  grid-template-columns: 150px 1fr;
  gap: 1rem 2rem;
  align-items: start;
  max-width: 600px;
  padding: 2rem;
}

.form-label {
  padding-top: 0.5rem;
  font-weight: 500;
  color: #333333;
}

.form-input {
  padding: 0.75rem 1rem;
  border: 1px solid #cccccc;
  border-radius: 6px;
  font-size: 1rem;
}

.form-input:focus {
  outline: none;
  border-color: #4361ee;
  box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.1);
}

.form-textarea {
  resize: vertical;
  min-height: 120px;
}

.form-actions {
  grid-column: 2;
  display: flex;
  justify-content: flex-end;
}

.btn-submit {
  padding: 0.75rem 2rem;
  background-color: #4361ee;
  color: #ffffff;
  border: none;
  border-radius: 6px;
  font-size: 1rem;
  cursor: pointer;
  transition: background-color 0.2s ease;
}

.btn-submit:hover {
  background-color: #3651d4;
}

grid-template-columns: 150px 1frでラベル列を固定幅、入力欄列を可変幅に設定しています。align-items: startにより、複数行のテキストエリアでもラベルが上揃えになります。

パターン4-2: レスポンシブフォームレイアウト

モバイルでは縦並び、デスクトップでは横並びになるフォームです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.form-responsive {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  max-width: 600px;
  padding: 2rem;
}

.form-responsive .form-label {
  font-weight: 500;
  color: #333333;
  margin-bottom: -0.5rem;
}

@media (min-width: 640px) {
  .form-responsive {
    grid-template-columns: 150px 1fr;
    gap: 1rem 2rem;
    align-items: start;
  }

  .form-responsive .form-label {
    padding-top: 0.75rem;
    margin-bottom: 0;
  }

  .form-responsive .form-actions {
    grid-column: 2;
  }
}

パターン5: カードグリッドの高度なパターン

パターン5-1: 等高カードグリッド

すべてのカードの高さを自動的に揃えるパターンです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
.card-grid-equal-height {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
  padding: 2rem;
}

.card-equal {
  display: grid;
  grid-template-rows: auto 1fr auto;
  background-color: #ffffff;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.card-equal .card-image {
  width: 100%;
  height: 200px;
  object-fit: cover;
}

.card-equal .card-body {
  padding: 1.5rem;
}

.card-equal .card-footer {
  padding: 1rem 1.5rem;
  border-top: 1px solid #eeeeee;
  background-color: #fafafa;
}

カード自体もdisplay: gridにすることで、内部の構造(画像・本文・フッター)も制御できます。grid-template-rows: auto 1fr autoにより、本文エリアが伸縮してカードの高さが揃います。

パターン5-2: 特定のカードを強調するグリッド

プロモーションや重要なコンテンツを目立たせるパターンです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.card-grid-highlight {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 200px;
  gap: 1.5rem;
  padding: 1.5rem;
}

.card-highlight {
  background-color: #ffffff;
  border-radius: 12px;
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.card-highlight.primary {
  grid-column: span 2;
  grid-row: span 2;
  background: linear-gradient(135deg, #4361ee 0%, #3a0ca3 100%);
  color: #ffffff;
}

.card-highlight.secondary {
  grid-row: span 2;
  background: linear-gradient(135deg, #f72585 0%, #7209b7 100%);
  color: #ffffff;
}

.primary.secondaryクラスで特定のカードを大きく表示し、視覚的な階層構造を作成しています。

実装のベストプラクティス

CSS Gridを使ったレイアウト実装で注意すべきポイントをまとめます。

フォールバックを考慮する

古いブラウザへの対応が必要な場合、@supportsを使ってフォールバックを提供できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
/* フォールバック: Flexboxを使用 */
.layout-fallback {
  display: flex;
  flex-wrap: wrap;
}

.layout-fallback > * {
  flex: 1 1 300px;
}

/* Grid対応ブラウザ向け */
@supports (display: grid) {
  .layout-fallback {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  }

  .layout-fallback > * {
    flex: none;
  }
}

コンテンツの最小幅を考慮する

minmax()を使用する際は、コンテンツがはみ出さないよう最小値を適切に設定します。

1
2
3
4
5
6
7
8
9
/* 問題: 狭い画面でコンテンツがはみ出す可能性 */
.grid-problem {
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
}

/* 解決: min()関数で画面幅を考慮 */
.grid-solution {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 400px), 1fr));
}

min(100%, 400px)により、画面幅が400px未満の場合は100%を、それ以上の場合は400pxを最小値として使用します。

gapプロパティを活用する

マージンではなくgapを使うことで、子要素間の余白を一元管理できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
/* 非推奨: 個別マージン */
.grid-old .item {
  margin: 0.5rem;
}

/* 推奨: gapプロパティ */
.grid-new {
  display: grid;
  gap: 1rem;
}

gapを使うと最初と最後の要素に不要な余白が生じることもなく、行と列で異なる間隔(gap: 1rem 2rem)も簡単に指定できます。

まとめ

本記事では、CSS Gridを使った実践的なレイアウトパターンを解説しました。

パターン 主な用途 ポイント
ページレイアウト サイト全体の構成 grid-template-areasで視覚的に定義
画像ギャラリー サムネイル一覧 auto-fill/auto-fitでレスポンシブ対応
ダッシュボード 管理画面のウィジェット配置 spanで柔軟なサイズ調整
フォーム ラベルと入力欄の整列 2カラムグリッドで整然と配置

CSS Gridは複雑に見えますが、基本パターンを押さえておけば応用が効きます。まずは本記事のコードをそのまま使い、徐々にカスタマイズしていくことで、自在にグリッドレイアウトを操れるようになるでしょう。

次の記事「FlexboxとCSS Gridの使い分けガイド」では、FlexboxとGridをどのように使い分けるべきか、それぞれの得意分野と組み合わせパターンを解説します。

参考リンク