books.chapter 710日で覚えるCSS

Day 7: CSS Grid

今日学ぶこと

  • CSS Gridの基本概念
  • グリッドコンテナのプロパティ
  • グリッドアイテムの配置
  • テンプレートエリア
  • FlexboxとGridの使い分け

CSS Gridとは

CSS Gridは、2次元のレイアウトを作るための仕組みです。行(row)と列(column)を同時に制御できます。

flowchart LR
    subgraph Compare["Flexbox vs Grid"]
        Flex["Flexbox<br>1次元<br>横並び or 縦並び"]
        Grid["Grid<br>2次元<br>行 × 列"]
    end
    style Flex fill:#3b82f6,color:#fff
    style Grid fill:#22c55e,color:#fff
.container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 16px;
}

グリッドの基本

grid-template-columns / grid-template-rows

/* 3等分 */
.grid-3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
}

/* repeat関数 */
.grid-3 {
    grid-template-columns: repeat(3, 1fr);
}

/* 固定 + 可変 */
.sidebar-layout {
    grid-template-columns: 250px 1fr;
}

/* 行の指定 */
.grid {
    grid-template-rows: 80px 1fr 60px;
}

fr 単位

fr(fraction)は、残りスペースを分配する単位です。

/* 1:2:1 の比率で分配 */
grid-template-columns: 1fr 2fr 1fr;

/* 200px固定 + 残りを均等分配 */
grid-template-columns: 200px 1fr 1fr;
説明
1fr 残りスペースの1割当
200px 固定200px
auto コンテンツに合わせる
minmax(200px, 1fr) 最小200px〜最大1fr

gap(間隔)

.grid {
    gap: 16px;            /* 行と列の両方 */
    gap: 16px 24px;       /* 行間 列間 */
    row-gap: 16px;
    column-gap: 24px;
}

アイテムの配置

行と列の番号で配置

.item {
    grid-column: 1 / 3;    /* 1列目から3列目まで(2列分) */
    grid-row: 1 / 2;       /* 1行目から2行目まで(1行分) */
}

/* span を使う */
.item-wide {
    grid-column: span 2;   /* 2列分 */
}

.item-tall {
    grid-row: span 3;      /* 3行分 */
}
flowchart TB
    subgraph GridLines["グリッド線の番号"]
        L["列: 1 | 2 | 3 | 4<br>行: 1<br>──────<br>行: 2<br>──────<br>行: 3"]
    end
    style L fill:#3b82f6,color:#fff

grid-template-areas

名前を付けてレイアウトを視覚的に定義できます。

.layout {
    display: grid;
    grid-template-areas:
        "header  header  header"
        "sidebar content content"
        "footer  footer  footer";
    grid-template-columns: 250px 1fr 1fr;
    grid-template-rows: 80px 1fr 60px;
    min-height: 100vh;
    gap: 0;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer  { grid-area: footer; }

ポイント: grid-template-areasを使うと、レイアウトをASCIIアートのように視覚的に定義できます。


自動配置

auto-fill と auto-fit

/* auto-fill: カラム数を自動調整(空スペース保持) */
.grid-auto {
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}

/* auto-fit: カラム数を自動調整(空スペースを埋める) */
.grid-auto-fit {
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
説明
auto-fill 可能な限り列を作る(空セルあり)
auto-fit 可能な限り列を作り、アイテムを引き伸ばす

推奨: レスポンシブなカードグリッドにはrepeat(auto-fit, minmax(250px, 1fr))がよく使われます。メディアクエリなしでレスポンシブなグリッドを実現できます。


配置プロパティ

コンテナ全体

.grid {
    justify-items: center;    /* セル内の水平方向 */
    align-items: center;      /* セル内の垂直方向 */
    place-items: center;      /* 上記2つのショートハンド */

    justify-content: center;  /* グリッド全体の水平方向 */
    align-content: center;    /* グリッド全体の垂直方向 */
    place-content: center;    /* 上記2つのショートハンド */
}

個別のアイテム

.item {
    justify-self: end;     /* このアイテムの水平方向 */
    align-self: center;    /* このアイテムの垂直方向 */
    place-self: center end;
}

Flexbox と Grid の使い分け

状況 推奨
横一列のナビゲーション Flexbox
カードの横並び Flexbox or Grid
ページ全体のレイアウト Grid
2次元のグリッドレイアウト Grid
要素の中央寄せ どちらでもOK
コンテンツサイズで幅が決まる Flexbox
列数や幅を明示的に制御 Grid
flowchart TB
    Q1{"2次元の<br>レイアウト?"}
    Q2{"コンテンツサイズ<br>で決まる?"}
    Grid["CSS Grid"]
    Flex["Flexbox"]
    Q1 -->|"はい"| Grid
    Q1 -->|"いいえ"| Q2
    Q2 -->|"はい"| Flex
    Q2 -->|"いいえ"| Grid
    style Grid fill:#22c55e,color:#fff
    style Flex fill:#3b82f6,color:#fff

実践: ダッシュボードレイアウト

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: system-ui, sans-serif;
    color: #1e293b;
}

/* ページ全体のレイアウト */
.dashboard {
    display: grid;
    grid-template-areas:
        "sidebar header"
        "sidebar main";
    grid-template-columns: 250px 1fr;
    grid-template-rows: 64px 1fr;
    min-height: 100vh;
}

.header {
    grid-area: header;
    background: white;
    border-bottom: 1px solid #e2e8f0;
    display: flex;
    align-items: center;
    padding: 0 24px;
}

.sidebar {
    grid-area: sidebar;
    background: #1e293b;
    color: white;
    padding: 24px;
}

.main {
    grid-area: main;
    background: #f8fafc;
    padding: 24px;
}

/* カードグリッド */
.stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 16px;
    margin-bottom: 24px;
}

.stat-card {
    background: white;
    padding: 24px;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.stat-card h3 {
    font-size: 0.875rem;
    color: #64748b;
    margin-bottom: 8px;
}

.stat-card .number {
    font-size: 2rem;
    font-weight: 700;
}

/* メインコンテンツのグリッド */
.content-grid {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 24px;
}

.panel {
    background: white;
    padding: 24px;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

まとめ

プロパティ 対象 説明
display: grid コンテナ Grid有効化
grid-template-columns コンテナ 列の定義
grid-template-rows コンテナ 行の定義
grid-template-areas コンテナ 名前で領域定義
gap コンテナ セル間の間隔
grid-column / grid-row アイテム 配置位置
grid-area アイテム 名前付き領域に配置
fr 残りスペースの分配

重要ポイント

  1. fr単位で柔軟なスペース分配
  2. **grid-template-areas**で視覚的にレイアウトを定義
  3. **auto-fit + minmax()**でレスポンシブグリッド
  4. Flexboxとの使い分けを意識する

練習問題

問題1: 基本

3列のカードグリッドをCSS Gridで作成してください。

問題2: 応用

grid-template-areasを使って、ヘッダー・サイドバー・メイン・フッターの4領域レイアウトを作成してください。

チャレンジ問題

auto-fitminmax()を使って、メディアクエリなしで画面幅に応じてカラム数が変化するレスポンシブグリッドを作成してください。


参考リンク


次回予告: Day 8では「レスポンシブデザイン」について学びます。メディアクエリとモバイルファーストのアプローチをマスターしましょう。