MechaToraのブログ

記事のアイキャッチ画像
技術・開発

CSS Grid完全ガイド - 現代的なレイアウト実装の決定版

「CSSのレイアウトが苦手」「Flexboxだけでは複雑なレイアウトが作れない」——そんな悩みを解決するのがCSS Gridです。2017年に主要ブラウザで対応が完了し、今や現代的なWebサイトには欠かせない技術となっています。

この記事では、MechaToraで15個のツールを作る中で習得したCSS Gridの使い方を、実践的なコード例とともに解説します。基本的な使い方から、レスポンシブ対応、Flexboxとの使い分けまで、実務で使える内容をお伝えします。

CSS Gridとは

2次元レイアウトシステム

CSS Gridは、行(row)と列(column)の両方を同時に制御できる、2次元のレイアウトシステムです:

FlexboxとCSS Gridの使い分け

用途 Flexbox CSS Grid
ナビゲーションバー
カード一覧
ページ全体のレイアウト
フォーム
センタリング

私の使い分けルール:

CSS Gridの基本

セクション画像

最もシンプルな例

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

<!-- CSS -->
.grid-container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr; /* 3列、均等幅 */
    gap: 1rem; /* 要素間の隙間 */
}

.item {
    background: #2563eb;
    color: white;
    padding: 1rem;
    text-align: center;
}

fr単位とは

fr(fraction、分数)は、利用可能なスペースを分割する単位です:

/* 1:1:1 の比率で3列 */
grid-template-columns: 1fr 1fr 1fr;

/* 1:2:1 の比率で3列(中央が2倍の幅) */
grid-template-columns: 1fr 2fr 1fr;

/* 固定幅 + 可変幅 */
grid-template-columns: 200px 1fr 200px;

repeat()関数

同じパターンを繰り返す場合は、repeat()が便利:

/* 3列均等 */
grid-template-columns: repeat(3, 1fr);

/* 4列、交互に200pxと1fr */
grid-template-columns: repeat(2, 200px 1fr);

実践例1:カードグリッド

HTML構造

<div class="card-grid">
    <div class="card">
        <img src="app1.jpg" alt="地震モニター">
        <h3>地震モニター</h3>
        <p>リアルタイムで地震情報を通知</p>
    </div>
    <div class="card">
        <img src="app2.jpg" alt="日本酒検索">
        <h3>日本酒検索</h3>
        <p>3万種類から検索</p>
    </div>
    <!-- ... 他のカード -->
</div>

CSS実装

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 2rem;
    padding: 2rem;
}

.card {
    background: white;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    overflow: hidden;
    transition: transform 0.2s;
}

.card:hover {
    transform: translateY(-5px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

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

.card h3 {
    padding: 1rem 1rem 0.5rem;
    margin: 0;
}

.card p {
    padding: 0 1rem 1rem;
    color: #666;
}

auto-fit と minmax() の魔法

auto-fitminmax()を組み合わせると、レスポンシブ対応が自動化されます:

/* 最小300px、最大1fr */
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));

/* 意味:
- カードは最低300px幅
- 画面幅に応じて列数が自動調整
- PC: 3〜4列
- タブレット: 2列
- スマホ: 1列
*/

auto-fit vs auto-fill

実践例2:ページ全体のレイアウト

セクション画像

Holy Grail Layout

ヘッダー、サイドバー、メイン、フッターを持つ典型的なレイアウト:

<!-- HTML -->
<div class="page-layout">
    <header>ヘッダー</header>
    <aside>サイドバー</aside>
    <main>メインコンテンツ</main>
    <footer>フッター</footer>
</div>

<!-- CSS -->
.page-layout {
    display: grid;
    grid-template-areas:
        "header header"
        "sidebar main"
        "footer footer";
    grid-template-columns: 250px 1fr;
    grid-template-rows: auto 1fr auto;
    min-height: 100vh;
    gap: 1rem;
}

header {
    grid-area: header;
    background: #1e40af;
    color: white;
    padding: 1rem;
}

aside {
    grid-area: sidebar;
    background: #f3f4f6;
    padding: 1rem;
}

main {
    grid-area: main;
    padding: 1rem;
}

footer {
    grid-area: footer;
    background: #374151;
    color: white;
    padding: 1rem;
    text-align: center;
}

/* レスポンシブ対応 */
@media (max-width: 768px) {
    .page-layout {
        grid-template-areas:
            "header"
            "main"
            "sidebar"
            "footer";
        grid-template-columns: 1fr;
    }
}

grid-template-areas の利点

実践例3:フォームレイアウト

<!-- HTML -->
<form class="form-grid">
    <label for="name">名前</label>
    <input type="text" id="name" />

    <label for="email">メールアドレス</label>
    <input type="email" id="email" />

    <label for="message">メッセージ</label>
    <textarea id="message" rows="5"></textarea>

    <div></div> <!-- 空のdiv(ラベル列を埋めるため) -->
    <button type="submit">送信</button>
</form>

<!-- CSS -->
.form-grid {
    display: grid;
    grid-template-columns: 150px 1fr;
    gap: 1rem;
    max-width: 600px;
    margin: 2rem auto;
}

.form-grid label {
    align-self: center;
    font-weight: bold;
}

.form-grid input,
.form-grid textarea {
    padding: 0.5rem;
    border: 1px solid #d1d5db;
    border-radius: 4px;
}

.form-grid button {
    background: #2563eb;
    color: white;
    padding: 0.75rem 2rem;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

/* スマホではラベルを上に配置 */
@media (max-width: 640px) {
    .form-grid {
        grid-template-columns: 1fr;
    }
}

実践例4:ダッシュボード

<!-- HTML -->
<div class="dashboard">
    <div class="widget large">大きいウィジェット</div>
    <div class="widget">ウィジェット1</div>
    <div class="widget">ウィジェット2</div>
    <div class="widget">ウィジェット3</div>
    <div class="widget tall">縦長ウィジェット</div>
    <div class="widget">ウィジェット4</div>
</div>

<!-- CSS -->
.dashboard {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    grid-auto-rows: 200px; /* 各行の高さ */
    gap: 1.5rem;
    padding: 1.5rem;
}

.widget {
    background: white;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    padding: 1.5rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* 大きいウィジェット:2列×2行 */
.widget.large {
    grid-column: span 2;
    grid-row: span 2;
}

/* 縦長ウィジェット:2行 */
.widget.tall {
    grid-row: span 2;
}

grid-column と grid-row

特定の要素だけサイズを変える:

/* 2列分のスペースを占有 */
grid-column: span 2;

/* 2行分のスペースを占有 */
grid-row: span 2;

/* より明示的な書き方 */
grid-column: 1 / 3;  /* 1列目から3列目の手前まで */
grid-row: 2 / 4;     /* 2行目から4行目の手前まで */

よく使うCSSプロパティ一覧

コンテナ(親要素)

プロパティ 説明
display Grid有効化 grid
grid-template-columns 列の定義 1fr 2fr 1fr
grid-template-rows 行の定義 auto 1fr auto
gap 要素間の隙間 1rem
grid-template-areas エリア名で配置 "header header"

アイテム(子要素)

プロパティ 説明
grid-column 列の占有範囲 span 2
grid-row 行の占有範囲 1 / 3
grid-area エリア名を指定 header
justify-self 自身の水平位置 center
align-self 自身の垂直位置 start

MechaToraでの実際の使用例

トップページのアプリ一覧

.app-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 2rem;
    padding: 2rem;
    max-width: 1200px;
    margin: 0 auto;
}

@media (max-width: 640px) {
    .app-grid {
        grid-template-columns: 1fr;
        padding: 1rem;
        gap: 1rem;
    }
}

ブログ記事一覧

.article-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
    gap: 2.5rem;
}

.article-card {
    display: grid;
    grid-template-rows: 200px auto 1fr auto;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

まとめ

CSS Gridを使うべき場面

Flexboxを使うべき場面

最初に覚えるべき3つのパターン

  1. 均等3列グリッドgrid-template-columns: repeat(3, 1fr)
  2. レスポンシブカードrepeat(auto-fit, minmax(300px, 1fr))
  3. ページレイアウトgrid-template-areas

CSS Gridは最初は難しく感じるかもしれませんが、基本パターンを覚えてしまえば、あらゆるレイアウトが簡単に実現できます。MechaToraでは、全15個のツールでCSS Gridを活用し、レスポンシブ対応を効率化しています。

ぜひ、実際に手を動かして試してみてください!