HTML/CSS / LESSON 14 / HT14

HTML/CSS:Grid

1学習の目的

2基礎解説

FlexboxとGridは競合ではなく役割分担です。1方向に並べるなら Flexbox、行と列の格子を作るなら Grid——この基準で選びます。

プロパティ役割
display: grid格子にする出発点
grid-template-columns列の指定1fr 1fr 1fr
gapマス目の間隔20px
grid-column横方向の結合span 2
✅ 覚えるべき重要ポイント
  1. fr は「残りの空間の分け前」1fr 1fr 1fr なら3等分、200px 1fr なら「200px固定+残り全部」になる。gap を引いた残りを分けてくれるので、自分で計算する必要がない。
  2. repeat(3, 1fr)1fr 1fr 1fr の省略形。列数が多いときに便利で、repeat(12, 1fr) のような指定も簡潔に書ける。
  3. 要素は自動的に次の行へ流れる。3列を指定して4つ置けば、4つ目は2行目の先頭に来る。行数を指定する必要がない
  4. grid-column: span 2 で横に2マス分使える。表のセル結合(HT04の colspan)と同じ感覚で、特定の要素だけ大きくできる。
  5. repeat(auto-fill, minmax(150px, 1fr)) と書くと、画面幅に応じて列数が自動で変わる。メディアクエリを書かずにレスポンシブなカード一覧が作れる。

現場使用例:商品一覧、写真ギャラリー、ダッシュボード、ページ全体の骨組み。「縦横に整然と並べたい」場面はすべてGridの出番

/* 基本:3等分の列を作る */
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 20px;
}

/* repeat で省略形 */
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

/* 固定 + 伸縮の組み合わせ */
.layout {
  display: grid;
  grid-template-columns: 200px 1fr;   /* サイドバー + 本文 */
  gap: 24px;
}

/* 特定の要素だけ横に2マス分 */
.wide {
  grid-column: span 2;
}

/* ⭐ 画面幅に応じて列数が自動で変わる */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 16px;
}
/* 150px以上を保ちつつ、入るだけ列を作る */

/* 行の高さも指定できる */
.page {
  display: grid;
  grid-template-rows: 60px 1fr 40px;  /* ヘッダー / 本文 / フッター */
  height: 100vh;
}

/* 中央揃えの最短記法 */
.center {
  display: grid;
  place-items: center;    /* 上下左右まとめて中央 */
  height: 300px;
}

3基本ドリル(10問)

HT14-D01 3等分の列を持つGridを作り、3つの div を配置せよ(親の幅 600px、gap なし、高さ 50px)。 コーディング★☆☆無料
期待される結果

3つが200pxずつ

ヒント

grid-template-columns: 1fr 1fr 1fr; と書く。

模範解答
<style>
  .grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    width: 600px;
  }

  .grid div {
    height: 50px;
    background-color: #ccc;
  }
</style>

<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>
解説

1fr は「残りの空間を1つ分」。3つ並べれば3等分になり、600px なら各200pxになる。

HT14-D02 grid-template-columns: 1fr 1fr はどういう意味か。
A. 幅1pxの列を2つ B. 幅を2等分した列を2つ C. 2行作る D. 列を自動で決める
選択★☆☆無料
期待される結果

解答 == B

ヒント

fr は fraction(分数・割合)の略。

模範解答
B
解説

fr は空間の「分け前」を表す。1fr と 1fr なら1:1、1fr と 2fr なら1:2の比率で分けられる。

HT14-D03 repeat を使って4等分の列を作り、4つの div を配置せよ(親の幅 800px、高さ 40px)。 コーディング★☆☆無料
期待される結果

4つが200pxずつ

ヒント

repeat(4, 1fr) と書くと 1fr 1fr 1fr 1fr と同じ。

模範解答
<style>
  .grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    width: 800px;
  }

  .grid div {
    height: 40px;
    background-color: #ccc;
  }
</style>

<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>
解説

repeat は繰り返しの省略形。12列のグリッドなども repeat(12, 1fr) で簡潔に書ける。

HT14-D04 Gridレイアウトを開始するコードを完成させよ。 穴埋め★☆☆無料
コード
<style>
  .grid {
    display: ____;
    grid-template-columns: 1fr 1fr;
  }
</style>

<div class="grid">
  <div>A</div>
  <div>B</div>
</div>
期待される結果

display が grid

ヒント

「格子」を意味する4文字の値。

模範解答
grid
解説

display: grid が出発点。Flexbox と同じく、指定するのは親だけでよい。

HT14-D05 3列のGridに4つの要素を置くとどうなるか。
A. エラーになる B. 4つ目が2行目に移る C. 4列になる D. 4つ目が消える
選択★☆☆無料
期待される結果

解答 == B

ヒント

行数は自動的に増える。

模範解答
B
解説

要素は自動的に次の行へ流れる。行数を指定する必要がないので、要素数が変わっても崩れない。

HT14-D06 サイドバー(200px固定)と本文(残り全部)のGridレイアウトを作れ(親の幅 600px、gap なし)。 コーディング★★☆広告解放
期待される結果

200pxと400px

ヒント

grid-template-columns: 200px 1fr; と書く。

模範解答
<style>
  .layout {
    display: grid;
    grid-template-columns: 200px 1fr;
    width: 600px;
  }

  .layout div {
    height: 40px;
  }

  .sidebar { background-color: #ddd; }
  .main    { background-color: #f5f5f5; }
</style>

<div class="layout">
  <div class="sidebar">サイドバー</div>
  <div class="main">本文</div>
</div>
解説

固定と伸縮を混ぜられる。Flexboxでも同じことができるが、Gridなら列の定義を1行で表現できる。

HT14-D07 要素を横に2マス分広げるコードを完成させよ。 穴埋め★★☆広告解放
コード
<style>
  .grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    width: 400px;
  }

  .wide {
    grid-column: ____ 2;
  }
</style>

<div class="grid">
  <div class="wide">横長</div>
  <div>A</div>
  <div>B</div>
</div>
期待される結果

wideが400px

ヒント

「〜個分にまたがる」を意味する4文字のキーワード。

模範解答
span
解説

span 2 で2マス分を占める。表のセル結合(HT04の colspan)と同じ考え方。

HT14-D08 FlexboxとGridの使い分けとして適切なのはどれか。
A. Gridのほうが新しいので常にGrid B. 1方向ならFlexbox、行と列の格子ならGrid C. Flexboxのほうが速い D. 違いはない
選択★★☆広告解放
期待される結果

解答 == B

ヒント

それぞれ得意分野が違う。

模範解答
B
解説

役割分担で選ぶ。ヘッダーの横並びはFlexbox、商品一覧の格子はGrid——実務では両方を併用する。

HT14-D09 gap 20px の3列Gridを作り、6つの div を配置せよ(親の幅 640px、高さ 40px)。 コーディング★★☆広告解放
期待される結果

各列が200px、2行になる

ヒント

gap を引いた残りが3等分される(640 − 40 = 600 → 各200px)。

模範解答
<style>
  .grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
    width: 640px;
  }

  .grid div {
    height: 40px;
    background-color: #ccc;
  }
</style>

<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
</div>
解説

gap の分は自動的に差し引かれる。640px から gap 2つ分(40px)を引いた600pxが3等分され、各200pxになる。

HT14-D10 place-items: center を使い、高さ 200px の領域の中央に文字を配置せよ。 コーディング★★☆広告解放
期待される結果

place-itemsがcenter

ヒント

place-items は align-items と justify-items をまとめた指定。

模範解答
<style>
  .center {
    display: grid;
    place-items: center;
    height: 200px;
    background-color: #eee;
  }
</style>

<div class="center">
  <span>中央に配置</span>
</div>
解説

Gridなら1行で中央揃えができる。Flexboxでは2行必要だった指定が、place-items でまとまる。

4実践シナリオ(5問)

HT14-S01 【商品一覧】3列のGridで6つの商品カードを並べよ(親の幅 640px、gap 20px、カードに padding 16px・枠線・box-sizing)。 コーディング★★☆広告解放
期待される結果

3列2行、各200px

ヒント

repeat(3, 1fr) と gap を組み合わせる。

模範解答
<style>
  * {
    box-sizing: border-box;
  }

  .products {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
    width: 640px;
  }

  .card {
    padding: 16px;
    border: 1px solid #ddd;
  }
</style>

<div class="products">
  <div class="card">商品1</div>
  <div class="card">商品2</div>
  <div class="card">商品3</div>
  <div class="card">商品4</div>
  <div class="card">商品5</div>
  <div class="card">商品6</div>
</div>
解説

Flexboxで同じことをするには幅の計算が必要だった。Gridなら「3列」と書くだけで、gap を含めた計算はブラウザが行う。

HT14-S02 【自動で列数が変わる一覧】repeat(auto-fill, minmax(150px, 1fr)) を使い、4つのカードを配置せよ(親の幅 640px、gap 16px)。何列になるか予想してから確認すること。 コーディング★★☆広告解放
期待される結果

3列になり、4つ目が2行目へ

ヒント

auto-fill は「入るだけ列を作る」、minmax は「最小150px・最大1fr」の意味。

模範解答
<style>
  .cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 16px;
    width: 640px;
  }

  .card {
    height: 80px;
    background-color: #ddd;
  }
</style>

<div class="cards">
  <div class="card">1</div>
  <div class="card">2</div>
  <div class="card">3</div>
  <div class="card">4</div>
</div>
解説

4列ではなく3列になった。4列だと 150×4 + 16×3 = 648px で640pxを超えるため、ブラウザが3列と判断した。各カードは (640−32)÷3 ≒ 203px に広がり、4つ目は2行目へ。画面幅が変われば列数も自動で変わるので、メディアクエリを書かずにレスポンシブになる。

HT14-S03 【特定のカードだけ大きく】2列のGridで、1つ目だけ横2マス分にし、残り2つを通常サイズで配置せよ(親の幅 400px、gap なし)。 コーディング★★☆広告解放
期待される結果

1つ目が400px、他が200px

ヒント

1つ目のクラスに grid-column: span 2; を指定する。

模範解答
<style>
  .grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    width: 400px;
  }

  .grid div {
    height: 60px;
    background-color: #ccc;
  }

  .wide {
    grid-column: span 2;
    background-color: #999;
  }
</style>

<div class="grid">
  <div class="wide">注目商品</div>
  <div>商品A</div>
  <div>商品B</div>
</div>
解説

1つだけ目立たせたいときに有効。ニュースサイトのトップ記事や、ダッシュボードの主要指標などで使われる。

HT14-S04 【ページ全体の骨組み】行の高さを指定し、ヘッダー 60px・本文(残り全部)・フッター 40px の3行Gridを作れ(全体の高さ 300px)。 コーディング★★★広告解放
期待される結果

60px / 200px / 40px

ヒント

grid-template-rows: 60px 1fr 40px; と書く。

模範解答
<style>
  .page {
    display: grid;
    grid-template-rows: 60px 1fr 40px;
    height: 300px;
  }

  header { background-color: #ddd; }
  main   { background-color: #f5f5f5; }
  footer { background-color: #ddd; }
</style>

<div class="page">
  <header>ヘッダー</header>
  <main>本文エリア</main>
  <footer>フッター</footer>
</div>
解説

本文が残りの高さをすべて使う(300 − 60 − 40 = 200px)。height: 100vh にすれば、画面の高さいっぱいに広がるページになる。

HT14-S05 【比率の異なる列】1fr 2fr の2列Gridを作り、1:2の比率で分割せよ(親の幅 600px、gap なし)。 コーディング★★★広告解放
期待される結果

200pxと400px

ヒント

1fr と 2fr なら、合計3等分のうち1つ分と2つ分になる。

模範解答
<style>
  .grid {
    display: grid;
    grid-template-columns: 1fr 2fr;
    width: 600px;
  }

  .grid div {
    height: 50px;
  }

  .narrow { background-color: #ddd; }
  .wide   { background-color: #bbb; }
</style>

<div class="grid">
  <div class="narrow">1fr</div>
  <div class="wide">2fr</div>
</div>
解説

fr は比率なので、合計で割られる。1fr + 2fr = 3等分となり、600px なら200pxと400pxに分かれる。

5仕上げ課題

HT14-FINAL 【ダッシュボードのレイアウト】Gridを使い、格子状のダッシュボードを作れ。

① 全体の骨組み.page
display: gridgrid-template-rows: 64px 1fr、高さ 500px、幅 900px
・中身:header と div.body

② 本体の2カラム.body
display: gridgrid-template-columns: 220px 1frgap: 20px
・中身:aside.sidebar と main.content

③ カード一覧.cards、main の中)
display: gridgrid-template-columns: repeat(3, 1fr)gap: 16px
・カードを4つ配置し、1つ目だけ grid-column: span 3(横いっぱい)
・カードに padding 16px・枠線 1px solid #ddd・box-sizing

確認したいこと
.content の幅が660px(900 − 220 − 20)
・1つ目のカードが660px(3列ぶん)、残り3つが約209pxずつ
・header の高さが64px、body が436px
総合★★★広告解放
期待される結果

すべてのGridレイアウトと寸法が正しい

ヒント

Gridを3階層に入れ子にする。span 3 で1つ目のカードが3列分を占め、残り3つが2行目に並ぶ。660px から gap 32px を引いた628pxが3等分される。

模範解答
<style>
  * {
    box-sizing: border-box;
  }

  .page {
    display: grid;
    grid-template-rows: 64px 1fr;
    width: 900px;
    height: 500px;
  }

  .page > header {
    background-color: #0066cc;
    color: #ffffff;
    padding: 0 20px;
    display: flex;
    align-items: center;
  }

  .body {
    display: grid;
    grid-template-columns: 220px 1fr;
    gap: 20px;
  }

  .sidebar {
    background-color: #f0f0f0;
    padding: 16px;
  }

  .content {
    padding: 16px 0;
  }

  .cards {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
  }

  .card {
    padding: 16px;
    border: 1px solid #ddd;
    background-color: #ffffff;
  }

  .card-wide {
    grid-column: span 3;
  }
</style>

<div class="page">
  <header>ダッシュボード</header>

  <div class="body">
    <aside class="sidebar">メニュー</aside>

    <main class="content">
      <div class="cards">
        <div class="card card-wide">今月の売上サマリー</div>
        <div class="card">訪問者数</div>
        <div class="card">注文件数</div>
        <div class="card">平均単価</div>
      </div>
    </main>
  </div>
</div>
解説

Gridを3階層に入れ子にしている。ページ全体(行)→ 本体(列)→ カード一覧(格子)——それぞれの階層で「何を分割したいか」が違うので、Gridを重ねて使うのが自然な構成になる。

注目すべきは数値をほとんど計算していないことだ。.content の660px も、カードの約209px も、すべてブラウザが 1fr から算出している。もし親の幅を1200pxに変えても、すべてが自動的に追随する

grid-column: span 3 の効果も大きい。1つ目のカードだけが3列分を占め、残り3つは自動的に2行目へ流れる。要素の数が増えても減っても、この構造は崩れない。

そしてヘッダーの中では display: flex を使っている点にも注意してほしい。「格子を作るのはGrid、その中で縦横に揃えるのはFlexbox」——両者は競合せず、役割に応じて併用するのが実務の書き方だ。

次章ではレスポンシブ対応を学ぶ。今回作ったレイアウトを、スマホでも崩れないページに仕上げていく。