HTML/CSS:Grid
1学習の目的
- Gridで行と列を同時に制御できるようになる。Flexboxが苦手とする「縦横の格子」を、はるかに簡単に組めるようになる。
- fr 単位と auto-fill を理解する。画面幅に応じて自動で列数が変わるレイアウトが、1行で書けるようになる。
2基礎解説
FlexboxとGridは競合ではなく役割分担です。1方向に並べるなら Flexbox、行と列の格子を作るなら Grid——この基準で選びます。
| プロパティ | 役割 | 例 |
|---|---|---|
| display: grid | 格子にする | 出発点 |
| grid-template-columns | 列の指定 | 1fr 1fr 1fr |
| gap | マス目の間隔 | 20px |
| grid-column | 横方向の結合 | span 2 |
- fr は「残りの空間の分け前」。1fr 1fr 1fr なら3等分、200px 1fr なら「200px固定+残り全部」になる。gap を引いた残りを分けてくれるので、自分で計算する必要がない。
- repeat(3, 1fr) は 1fr 1fr 1fr の省略形。列数が多いときに便利で、repeat(12, 1fr) のような指定も簡潔に書ける。
- 要素は自動的に次の行へ流れる。3列を指定して4つ置けば、4つ目は2行目の先頭に来る。行数を指定する必要がない。
- grid-column: span 2 で横に2マス分使える。表のセル結合(HT04の colspan)と同じ感覚で、特定の要素だけ大きくできる。
- ⭐ 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問)
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になる。
A. 幅1pxの列を2つ B. 幅を2等分した列を2つ C. 2行作る D. 列を自動で決める 選択★☆☆無料
解答 == B
fr は fraction(分数・割合)の略。
B
fr は空間の「分け前」を表す。1fr と 1fr なら1:1、1fr と 2fr なら1:2の比率で分けられる。
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) で簡潔に書ける。
<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 と同じく、指定するのは親だけでよい。
A. エラーになる B. 4つ目が2行目に移る C. 4列になる D. 4つ目が消える 選択★☆☆無料
解答 == B
行数は自動的に増える。
B
要素は自動的に次の行へ流れる。行数を指定する必要がないので、要素数が変わっても崩れない。
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行で表現できる。
<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)と同じ考え方。
A. Gridのほうが新しいので常にGrid B. 1方向ならFlexbox、行と列の格子ならGrid C. Flexboxのほうが速い D. 違いはない 選択★★☆広告解放
解答 == B
それぞれ得意分野が違う。
B
役割分担で選ぶ。ヘッダーの横並びはFlexbox、商品一覧の格子はGrid——実務では両方を併用する。
各列が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になる。
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問)
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 を含めた計算はブラウザが行う。
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行目へ。画面幅が変われば列数も自動で変わるので、メディアクエリを書かずにレスポンシブになる。
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つだけ目立たせたいときに有効。ニュースサイトのトップ記事や、ダッシュボードの主要指標などで使われる。
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 にすれば、画面の高さいっぱいに広がるページになる。
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仕上げ課題
① 全体の骨組み(.page)
・display: grid、grid-template-rows: 64px 1fr、高さ 500px、幅 900px
・中身:header と div.body
② 本体の2カラム(.body)
・display: grid、grid-template-columns: 220px 1fr、gap: 20px
・中身:aside.sidebar と main.content
③ カード一覧(.cards、main の中)
・display: grid、grid-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」——両者は競合せず、役割に応じて併用するのが実務の書き方だ。
次章ではレスポンシブ対応を学ぶ。今回作ったレイアウトを、スマホでも崩れないページに仕上げていく。