CSS Grid Layoutの基本と具体的な使用例
2024.05.20 Posted by Coding_team
CSSで自由自在なレイアウト(Grid Layout)を作れるプロパティGridの基本的な使い方と具体的な使用例をご紹介します。
CSS Gridの特徴・Flexboxやfloatとの違い
CSS Gridのように、カラムレイアウトを作れるプロパティとしてFlexboxやfloatなどが思い浮かびますが
これらはあくまで1次元的なレイアウトであり、例えば左上から右など一方向に向かって子要素を配置していくものです。
Flexboxに関しては垂直方向中央揃えや子要素の並び替えなどの機能もありますが、それでもあくまで1次元です。
一方でCSS Grid Layoutは2次元レイアウトであり、例えば左上から右にも下にも子要素を配置することができたり、レイアウトの連結や、特定の子要素を特定の位置に配置するなど自由自在に配置できるという特徴があります。
CSS Gridの基本
まずはCSS Gridの基本的な使い方についてご紹介します。
例として、以下のHTMLを使います。
1 2 3 |
<div class="container"> <div class="item"></div> </div> |
親要素に指定するプロパティ
親要素に指定するプロパティとして、主に以下のようなものがあります。
(個人的によく使うものを抜粋しています)
- grid-template-columns (カラム数と幅を指定する)
- grid-template-rows (行数と高さを指定する)
- grid-auto-rows (行の高さのみ指定する)
- grid-auto-flow (子要素が配置される向きを指定する)
- gap (セルとセルの余白を指定する)
Grid Layoutを作るため、まずは親要素に例として以下のプロパティを指定します。
1 2 3 4 5 |
.container { display: grid; grid-template-columns: 100px 1fr; grid-template-rows: 100px 100px; } |
この時点で、以下のようなGrid Layoutが作成されます。
詳しく説明していきます。
grid-template-columnsプロパティ
CSS Gridの親要素に指定できるプロパティで、カラムの数と幅を指定します。
例えば3カラムを作るなら、以下のようにそれぞれのカラムの幅をスペース区切りで指定します。
1 |
grid-template-columns: 100px 100px 100px; /* 幅100pxの3カラム */ |
単位にはpxや%の他、autoやfrが使えるのですが、「fr」とはGrid Layoutで使える「残りの幅」というような指定です。 (Flexboxで言うところのflex-growに近いです)
例えば、grid-template-columnsの指定を以下のようにすると
1 2 3 4 5 |
.container { display: grid; grid-template-columns: 100px 1fr 2fr; /* 3カラム */ grid-template-rows: 100px 100px; } |
以下のようなGrid Layoutになります。
左のカラムが100pxなのに対し、残りの幅を1:2の比率で2カラム目・3カラム目と分割されています。
また、grid-template-columnsの値として、以下のように「auto」を指定すると
1 2 3 4 5 |
.container { display: grid; grid-template-columns: auto 1fr 2fr; /* カラム幅にautoを使用 */ grid-template-rows: 100px 100px; } |
以下のように子要素のサイズに合わせてカラムの幅が決まります。
grid-template-columns – CSS: カスケーディングスタイルシート | MDN
grid-template-rowsプロパティ
列(カラム)を指定するgrid-template-columnsプロパティに対し、行を指定するのが「grid-template-rows」プロパティです。
基本的な構文はgrid-template-columnsプロパティと一緒ですが、実用的な話、文章の増減などを考慮すると縦方向の長さをpxなど絶対的な単位で指定することは少ないため、以下のように「auto」で済ませることが個人的には多いです。
1 |
grid-template-rows: auto auto; |
さらに言えば、2行と決まっているのであればこのような書き方でも問題ないのですが、何行になるかわからない場合もあると思います。
その場合grid-template-rowsプロパティではなく、次のgrid-auto-rowsプロパティを使うことができます。
grid-template-rows – CSS: カスケーディングスタイルシート | MDN
grid-auto-rowsプロパティ
行の数と高さを指定するgrid-template-rowsプロパティとは異なり、行の高さのみを指定するのがgrid-auto-rowsプロパティです。
行の数が決まっている場合はgrid-template-rows
決まっていない場合はgrid-auto-rowsプロパティを使う
というイメージです。
この2つは併用することもできますが、個人的にはどちらかのみを使うことが多いです。
例えば、親要素の指定を以下のようにします。
1 2 3 4 5 |
.container { display: grid; grid-template-columns: auto auto; /* 2カラムで幅はauto */ grid-auto-rows: auto; /* 行の高さはauto */ } |
先ほどのgrid-template-rowsプロパティの代わりにgrid-auto-rowsプロパティで「auto」を指定しています。
すると以下のように縦方向にはずっとautoが適用され、積み重なっていきます。
grid-auto-rows – CSS: カスケーディングスタイルシート | MDN
grid-auto-flowプロパティ
子要素をどのような向き(順番)で配置していくか指定します。
Flexboxで言うところのflex-directionに近いです。
デフォルトの値は「row」で左上から右に向かってZ方向に子要素が配置されていきます。 (上の行から埋めようとする順番)
他に「column」という値も指定でき、その場合左上から下に向かって配置されていきます。 (左の列から埋めようとする順番)
grid-auto-flow – CSS: カスケーディングスタイルシート | MDN
gapプロパティ
Flexboxでも使えるプロパティで、セルとセル (子要素同士) の余白を指定します。
例えば以下のようにすると
1 2 3 4 5 6 |
.container { display: grid; grid-template-columns: 100px 1fr; grid-template-rows: 100px 100px; gap: 10px 20px; /* 縦方向に10px 横方向に20px */ } |
以下のように、縦方向に10px、横方向に20pxの余白が入ります。
縦横共に20pxとしたい場合は gap: 20px; と短縮できます。
gap (grid-gap) – CSS: カスケーディングスタイルシート | MDN
子要素に指定するプロパティ
子要素に指定するプロパティとして、主に以下のようなものがあります。
(個人的によく使うものを抜粋しています)
- grid-column (列位置を指定する)
- grid-row (行位置を指定する)
- align-self (セル内での垂直方向の位置を指定する)
- justify-self (セル内での水平方向の位置を指定する)
(いま一度) 例として、以下のHTMLを使います。
1 2 3 |
<div class="container"> <div class="item"></div> </div> |
親要素は以下のような指定をしておきます。
1 2 3 4 5 |
.container { display: grid; grid-template-columns: 100px 1fr; grid-template-rows: 100px 100px; } |
ここで、子要素に以下のようなプロパティを指定すると
1 2 3 4 |
.item { grid-column: 1 / 2; grid-row: 1 / 3; } |
以下の水色の部分に子要素itemが配置されます。
1列目の、1行目と2行目のセル結合をしたような配置になっています。
他にも、子要素に以下のように指定すると
1 2 3 4 |
.item { grid-column: 1 / 3; grid-row: 1 / 2; } |
以下の水色の部分に子要素itemが配置されます。
今度は1行目で、1列目と2列目をセル結合したような配置です。
詳しく説明していきます。
grid-columnプロパティ
CSS Gridの子要素に指定できるプロパティで、子要素をどの列に配置するか指定します。
Grid Layoutでは、縦横それぞれの境界に「1、2、3・・・」という番号が振られており
grid-columnの値には、どの境界からどの境界に渡って配置するかをスラッシュ区切りで指定します。
1 2 3 |
.item { grid-column: 1 / 3; /* 列の境界1から3まで */ } |
すると以下のように配置されます。
また、隣り合わせの境界を指定する場合 (セル結合のようなことをしない場合) 以下のように短縮することもできます。
1 2 3 4 5 6 7 8 9 10 11 |
/* 例1 */ .item { grid-column: 1 / 2; /* 同義 */ grid-column: 1; /* 同義 */ } /* 例2 */ .item { grid-column: 3 / 4; /* 同義 */ grid-column: 3; /* 同義 */ } |
具体的には、以下のように指定すると
1 2 3 4 |
.item { grid-column: 1; grid-row: 1 / 3; } |
以下のように配置されます。
grid-column – CSS: カスケーディングスタイルシート | MDN
grid-rowプロパティ
CSS Gridの子要素に指定できるプロパティで、子要素をどの行に配置するか指定します。
前述したgrid-columnプロパティと書き方は全く同じで、例えば以下のように指定すると
1 2 3 4 |
.item { grid-column: 1 / 3; grid-row: 2; } |
以下のように配置されます。
grid-row – CSS: カスケーディングスタイルシート | MDN
align-selfプロパティ
Flexboxでも使えるプロパティで、子要素の垂直方向の位置を指定します。
例えば、以下のようなHTMLで
1 2 3 4 |
<div class="container"> <div class="item1">梨</div> <div class="item2">りんご</div> </div> |
以下のようにプロパティを指定すると
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
.container { display: grid; grid-template-columns: 100px 1fr; grid-template-rows: 100px 100px; } .item1 { grid-column: 1; grid-row: 1; align-self: end; /* 垂直方向下揃え */ } .item2 { grid-column: 2; grid-row: 2; align-self: center; /* 垂直方向中央揃え */ } |
以下のように、セル内での垂直方向の位置を指定できます。
他にもalign-selfの値として「start」(上揃え) などもありますが、個人的にはendかcenterの出番が多いです。
align-self – CSS: カスケーディングスタイルシート | MDN
justify-selfプロパティ
Flexboxを使っている人なら「見覚えが..いや..ん?」となることでしょう。
さらに、何となく想像がつくのではないでしょうか?
justify-selfプロパティはGrid Layoutの子要素に指定できるプロパティで、セル内での水平位置を指定します。
ちなみに、Flexboxでは使えません。
Flexboxでは親要素に「justify-content」プロパティを指定することで、子要素の水平位置を指定します。
Grid Layoutでも親要素にjustify-contentが使えるのですが、コンテナ(親要素)の丸ごと水平位置が変わってしまうので個人的に使うことは少ないです。
例えば、以下のようなHTMLで
1 2 3 4 |
<div class="container"> <div class="item1">梨</div> <div class="item2">りんご</div> </div> |
以下のようにプロパティを指定すると
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
.container { display: grid; grid-template-columns: 100px 1fr; grid-template-rows: 100px 100px; } .item1 { grid-column: 1; grid-row: 1; align-self: end; /* 垂直方向下揃え */ justify-self: end; /* 水平方向右揃え */ } .item2 { grid-column: 2; grid-row: 2; align-self: center; /* 垂直方向中央揃え */ justify-self: center; /* 水平方向中央揃え */ } |
以下のように、セル内での水平方向の位置を指定できます。
justify-self – CSS: カスケーディングスタイルシート | MDN
具体的な使用例
CSS Gridの具体的な使用例を3つご紹介します。
使用例① 画像とテキストの2カラム
PCでは画像とテキストの2カラムで、垂直方向中央揃えに。
SP (スマホ) ではタイトル・画像・本文の順番になるように。
このようなレイアウト、よくありますよね。
これ地味にFlexboxやfloatでは難しい…というか美しくは作れないのですが、Grid Layoutを使えばできます。
以下のようなHTMLを作ります。
1 2 3 4 5 |
<div class="container"> <h2 class="title">タイトル</h2> <p class="img"><img src="img/○○.jpg"></p> <p class="text">この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。</p> </div> |
そして、PCに対して以下のようなCSSを記述します。
(文字サイズやマージンなどの指定は省略しています)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* PC */ .container { display: grid; grid-template-columns: auto 1fr; gap: 20px; } .title { grid-column: 2; align-self: end; } .img { grid-row: 1 / 3; } .text { align-self: start; grid-column: 2; } |
SPは特にCSSの記述は不要です。順番に要素が配置されます。
以下がサンプルです。思い通りのレイアウトになりました。
タイトル
この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。
使用例② dl・dt・ddを使ったテーブル
説明リストのdl・dt・ddタグを使ってテーブルのようなレイアウトを作ってみます。
これ、Flexboxやfloatでも出来なくはないのですが、その場合カラムの幅を固定しなければならない一方
Grid Layoutなら子要素の文章量などに応じてカラムの幅が柔軟に動ける点において有利だと思います。
以下のようなHTMLを作ります。
1 2 3 4 5 6 7 8 9 10 |
<dl> <dt>春の果物</dt> <dd>オレンジ、キウイ、びわ</dd> <dt>夏の果物</dt> <dd>スイカ、メロン、桃、パイナップル</dd> <dt>秋の果物</dt> <dd>ぶどう、梨、りんご、柿</dd> <dt>冬の果物</dt> <dd>いちご、みかん</dd> </dl> |
そして、以下のようなCSSを記述します。
(枠線や余白などの指定は省略しています)
1 2 3 4 5 6 7 8 9 10 |
dl { display: grid; grid-template-columns: auto auto; } dt { grid-column: 1; } dd { grid-column: 2; } |
以下がサンプルです。
- 春の果物
- オレンジ、キウイ、びわ
- 夏の果物
- スイカ、メロン、桃、パイナップル
- 秋の果物
- ぶどう、梨、りんご、柿
- 冬の果物
- いちご、みかん
使用例③ カラムレイアウトの中身の高さを揃える
このようなレイアウトもよくありますよね。
注目して見ていただくと、タイトルの長さが違っても高さが揃っていたり、画像の高さが違っても垂直方向中央揃えになっていたり、ボタンが最下部で揃っていたりと、これもFlexboxだけでは柔軟性を担保しつつ再現することはおそらく不可能です。
(JSを使えばできますが)
これもGrid Layoutを使えばできます!と言いたいところなのですが、これに関してはHTMLのマークアップ的には少し微妙になってしまいます。
おまけ程度にご覧いただき、使いどころに応じて参考にしていただければと思います。
以下のようなHTMLを作ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<div class="container"> <h2 class="title left"><span>タイトル</span></h2> <p class="img left"><span><img src="img/css_grid_dummy01.png"></span></p> <p class="text left">この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。</p> <p class="btn left"><a href="todo">詳しくはこちら</a></p> <h2 class="title right"><span>タイトルが<br>2行になる場合</span></h2> <p class="img right"><span><img src="img/css_grid_dummy02.png"></span></p> <p class="text right">この文章はダミーです。</p> <p class="btn right"><a href="todo">詳しくはこちら</a></p> </div> |
HTMLのマークアップ的には、左の記事と右の記事を<article>タグなどで囲いたいですよね。
Gridの性質上、子要素はすべて並列に並べなければならないので、こうしています。
そして、以下のようなCSSを記述します。
(文字サイズや余白、ボタンなどの指定は省略しています)
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 |
.container { display: grid; grid-template-columns: 1fr 1fr; grid-auto-flow: column; gap: 0 20px; } .left { grid-column: 1; } .right { grid-column: 2; } .title span { display: flex; flex-direction: column; justify-content: center; height: 100%; } .img span { display: flex; flex-direction: column; justify-content: center; height: 100%; } .btn { align-self: end; } |
以下がサンプルです。思い通りのレイアウトになりました。
タイトル
この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。
タイトルが
2行になる場合
この文章はダミーです。
自由自在なレイアウトを作れるGrid Layout
その自由さゆえ、少し難しくとっつきにくさもあると思いますが、是非マスターしてコーディングに役立ててみてください。
以上、CSS Grid Layoutの基本と具体的な使用例でした。
関連記事こちらの記事も合わせてどうぞ。