もう怖くない!CSS Grid Layout 使い方完全解説!

もう怖くない!CSS Grid Layout 使い方完全解説!

この記事を書いた人

だいち

PENGIN BLOGメディア編集長。Web業界とは異業種の仕事をしながら、独学でWeb制作の世界に。副業でHP制作やコーディング代行、個人ブログの運営などに取り組み、現在はPENGINにてWebライティングやディレクションをしつつ、メディア運営全般を担当しています。(個人運営ブログ:https://daib-log.com/ )

目次

IEのサポートも終了することだし、なんとなく避けていたCSSのGridレイアウトにそろそろ慣れておいたほうがいいかも……そう考えているコーダーやフロントエンジニアの方もいらっしゃるはず。

ただ、学習を始めるにあたって、プロパティの種類や使い方、今までのCSSレイアウトとの違いなど、どの程度理解すべきなのか分かってないと不安ですよね。

そこで今回は、CSS Gridレイアウトの概念から、基礎的なプロパティの使い方についてまとめて解説します。

  • グリッドレイアウトとは?
  • グリッドレイアウトでコーディングはどう変わる?
  • 特有のプロパティや値の使い方
  • どんなデザイン構築に便利?

こんなことを知りたい方はぜひ最後までチェックしてくださいね!

グリッドレイアウト(Grid Layout)とは?

gridレイアウトイメージ

グリッドレイアウトとは、垂直方向と水平方向のラインで構成されるグリッドを用いて、2次元的に配置するレイアウトです。

CSSグリッドレイアウトでは、親要素にdisplayプロパティのgridinline-gridを指定することで、自動的にグリッドレイアウトが構成されます。

IEなどのブラウザ対応状況

CanIUseのgrid対応状況
(※2022年3月時点)引用 : “grid” | Can I use…

ほぼすべてのモダンブラウザに対応していますが、IEは他ブラウザとグリッドラインの概念が異なり、ベンダープレフィックスが必要であったり、未対応のプロパティもあります。

エディタやGulpなどのツールに、自動でプレフィックスを付与する拡張機能を導入すればある程度対応できますが、可能な限りIEは切り捨てられる環境で使用することが望ましいでしょう。

※当記事で初回するコードや解説については、IE対応を考慮していませんのでご了承ください。

グリッドレイアウトを使用したサイトの例

I/O 3000トップ画面

WebデザインギャラリーサイトのI/O 3000。

ギャラリーを同サイズのタイル型コンポーネントにまとめ、display:gridで整列させている、お手本のようなCSSグリッドレイアウトのサイトです。

OHArchitectureトップ画面

京都の注文住宅、建築設計、店舗デザインなどを手掛けるOHArchitectureのWebサイト。

全体をdisplay:gridグリッドで構成していますが、サイズの異なる画像やテキストをうまく配置することで、整列の中にメリハリをつけた見せ方が印象的です。

Arrivalトップ画面

イギリスの電気自動車を製造する企業、ArrivalのWebサイト。

FlexBoxとGridを組み合わせ、グリッドレイアウトを再現しています。

グリッドレイアウト関連の用語解説

CSSのグリッドレイアウトを理解するため、必要な用語について解説します。

グリッドコンテナ

グリッドコンテナイメージ

グリッド全体を構成する領域、グリッドで整列させる要素の親要素をグリッドコンテナと呼びます。

グリッドアイテム

グリッドコンテナの子要素をグリッドアイテムと呼びます。

親要素にdisplayプロパティでgridが指定されると、直下の子要素は自動的にグリッドアイテムに変化します。

この考え方はフレックスコンテナフレックスアイテムと同様です。

グリッドライン

グリッドを構成する線をグリッドラインと呼びます。

グリッドトラック

グリッドトラックのイメージ

水平、もしくは垂直で隣り合うグリッド線の間にある空間をグリッドトラックと呼びます。

グリッドセル

グリッドセルのイメージ

グリッドラインで生まれる最小のグリッド領域を指します。グリッドトラックより限定的な、単体のセルをグリッドセルと呼びます。

グリッドエリア

グリッドエリアのイメージ

グリッドコンテナでグリッドアイテムの位置や大きさを指定すると、そのグリッドセルはグリッドエリアと呼ぶ領域になります。

グリッドエリアの区切りがわかる検証ツール画像

グリッドエリアは、最低でも1つ以上のグリッドセルで形成されます。

css gridの基本的な使い方

CSSのGridは、displayプロパティに「grid」か「inline-grid」を書くだけで使えます。

<div class="grid-container">
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
</div>
.grid-container {
	display: grid;
	height: 400px;
}

/* わかりやすいように色分け */
.grid-item:nth-child(odd) {
	background-color: #a1a9c0;
}
.grid-item:nth-child(even) {
	background-color: #111934;
}

gridの値を指定した要素はグリッドコンテナとなり、子階層の数だけ自動的にグリッドトラックが形成されます。

display: grid指定時の初期状態

グリッドアイテムに何も指定していない初期値だと、グリッドアイテムはコンテナ内で垂直方向に並びます。

Grid関連の専用プロパティで行や列を指定することで、グリッドアイテムの配置や大きさをコントロールできます。

グリッドのセル数や大きさを指定

グリッドのレイアウト・行数や列数、大きさなどを決めるプロパティを紹介します。

grid-template-rows

grid-template-rowsは、グリッドコンテナ内の行数行の大きさを明示的に指定します。

.grid-container {
	display: grid;
	grid-template-rows: 100px 100px  100px  100px  100px;
}

半角スペースで区切って記述した値の数が行数になります。

上の例だと100pxの大きさで5行指定したことになります。

grid-template-rows

grid-template-columns

grid-template-columnsは、グリッドコンテナ内の列数列の大きさを明示的に指定します。

.grid-container {
	display: grid;
	grid-template-columns: 200px 200px 200px;
	height: 400px;
}

半角スペースで区切って記述した値の数が列数になります。

上では、200pxの大きさで3列指定しました。(行の大きさを指定していないので、heightプロパティで高さを確保しています)

grid-template-columns

検証ツールでもわかるように、グリッドラインが200pxの幅で3列分引かれているのがわかります。

設定したグリッドは3列ですが、HTMLの子要素は5つあるため、4つめと5つめの要素は次の行に移動しています。

grid-template-columnsとgrid-template-rowsを組み合わせて指定

.grid-container {
	display: grid;
	grid-template-columns: 200px 200px 200px;
	grid-template-rows: 100px 100px 100px 100px;
}

200pxの大きさで3列、100pxの大きさで4行のグリッドを指定しました。

columnsとrowsの組み合わせ

検証ツールで確認するとわかりますが、3列×4行のグリッドラインが引かれています。

設定で生じたグリッドセルの数=12グリッドアイテム(HTMLの要素)の数=5

上の画像のように、グリッドアイテムのほうが少ない場合、大きさを保ったままグリッドコンテナにおさまります。

<div class="grid-container">
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
</div>
.grid-container {
	display: grid;
	grid-template-columns: 200px 200px;
	grid-template-rows: 100px 100px;
}

上の場合だと、2列×2行のグリッドラインが引かれ、4つのグリッドセルができます。

グリッド数がグリッドアイテム数より少ない場合

設定で生じたグリッドセルの数=4グリッドアイテム(HTMLの要素)の数=5

グリッドアイテム数5つに対して、グリッドセル数は4つです。

グリッドセル数=グリッドアイテムが表示できる数のため、上の画像のように5つめのグリッドアイテムは表示されません。

これはHTMLのグリッドアイテム内に、コンテンツ(テキストや画像など)がないためです。

グリッドレイアウトでは、HTMLにコンテンツがない場合、コンテナで設定したグリッドセル数=グリッドアイテムの表示最大数になることを覚えておきましょう。

暗黙的なグリッドセルの大きさを指定

グリッドトラックやグリッドセルには、明示的に生成されるものと暗黙的に生成されるものがあります。

明示的に生成されるグリッドとは、grid-template-columns や grid-template-rows で指定したセルの数や大きさのことです。

一方、grid-template-columns や grid-template-rows で指定せずとも自動的に生成されるグリッドが暗黙的なグリッドです。

<div class="grid-container">
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
  <div class="grid-item"></div>
</div>
.grid-container {
	display: grid;
	grid-template-columns: 200px 200px;
	grid-template-rows: 100px 100px;
}
明示的なgridセル

上では「グリッドセル数よりグリッドアイテムが多い場合は表示されない」と説明しましたが、グリッドコンテナにおさまらなかったグリッドアイテムは、グリッドコンテナの外側に0pxの大きさで暗黙的にグリッドが生成されています。(画像の場合、5つめのグリッドアイテムが200 × 0となっている)

つまり、列2 × 行2 の4セルはプロパティで明示的に指定しましたが、5つめのグリッドアイテムは暗黙的なグリッドセル扱いになっています。

以上を踏まえて、暗黙的に生成されるグリッドトラックやグリッドセルのサイズを指定するプロパティを紹介します。

grid-auto-columns

grid-auto-columnsは暗黙的(grid-template-columns で指定されなかったグリッドサイズ)に生成される列の大きさを指定します。

.grid-container {
	display: grid;
	grid-auto-columns: 300px;
	grid-template-rows: 100px 100px 100px 100px 100px;
}
grid-auto-columnsの指定

grid-template-columnsで明示的に列の大きさを指定しないことで、大きさ 0 の列が暗黙的なグリッドとして生成されるため、grid-auto-columnsで300pxを指定しています。

grid-auto-rows

grid-auto-rowsは暗黙的(grid-template-rows で指定されなかったグリッドサイズ)に生成される行の大きさを指定します。

.grid-container {
	display: grid;
	grid-auto-rows: 300px;
	grid-template-columns: 200px 200px;
	grid-template-rows: 100px 100px;
}
grid-auto-rowsの指定

grid-templateのcolumnsとrowsで明示的なセルが4つできましたが、5つ目以降のセルが大きさ0の暗黙的なグリッドとなるため、そちらに対する行の大きさを300pxで指定しました。

グリッドコンテナ内のアイテム位置を指定

グリッドコンテナ内でのグリッドアイテムの並び方・配置を指定するプロパティを紹介します。

justify-content

justify-contentは、グリッドコンテナに記述することで、グリッドアイテムの横方向配置を定義します。

効果
start(初期値)グリッドコンテナの開始位置から配置
centerグリッドコンテナの左右中央に配置
endグリッドコンテナの終端位置に配置
space-between各グリッドアイテム間のスペースを均等に配置し、1番目と最後のグリッドアイテムはコンテナ左右の両端に配置
space-around各グリッドアイテム間のスペースを均等に配置し、1番目と最後のグリッドアイテムはコンテナ左右の両端から半分のスペースを空けて配置
space-evenly各グリッドアイテム間のスペースを均等に配置
/* いずれかをグリッドコンテナに記述 */
justify-content: start; (初期値)
justify-content: center;
justify-content: end;
justify-content: space-between;
justify-content: space-around;
justify-content: space-evenly;

※画像はクリックすると拡大表示されます。

justify-content-start
justify-content: start;(初期値)
justify-content-end
justify-content: end;
justify-content-center
justify-content: center;
justify-content-space-between
justify-content: space-between;
justify-content-space-around
justify-content: space-around;
justify-content-space-evenly
justify-content: space-evenly;

align-content

align-contentは、グリッドコンテナに記述することで、グリッドアイテムの縦方向配置を定義します。

効果
start(初期値)グリッドコンテナの開始位置から配置
centerグリッドコンテナの上下中央に配置
endグリッドコンテナの終端位置に配置
space-between各グリッドアイテム間のスペースを均等に配置し、1番目と最後のグリッドアイテムはコンテナ上下の両端に配置
space-around各グリッドアイテム間のスペースを均等に配置し、1番目と最後のグリッドアイテムはコンテナ上下の両端から半分のスペースを空けて配置
space-evenly各グリッドアイテム間のスペースを均等に配置
/* いずれかをグリッドコンテナに記述 */
align-content: start; (初期値)
align-content: center;
align-content: end;
align-content: space-between;
align-content: space-around;
align-content: space-evenly;

※画像はクリックすると拡大表示されます。

align-content-start
align-content: start;(初期値)
align-content-end
align-content: end;
align-content-center
align-content: center;
align-content-space-between
align-content: space-between;
align-content-space-around
align-content: space-around;
align-content-space-evenly
justify-content: space-evenly;

グリッドアイテム内のコンテンツ位置・大きさをまとめて指定

グリッドアイテムのコンテンツは、HTMLに記述したテキストや画像のことです。

justify-items

justify-itemsは、グリッドコンテナに記述することで、グリッドセル内左右方向の配置と、コンテンツの大きさを定義します。

セル内コンテンツへの効果
stretch(初期値)コンテンツ領域がグリッドセル全体に広がる
startグリッドセルの開始位置(左)に配置し、コンテンツ幅はコンテンツに依存、高さはセルいっぱいに広がる ※コンテンツがない場合幅0になる
endグリッドセルの終端位置(右)に配置し、コンテンツ幅はコンテンツに依存、高さはセルいっぱいに広がる ※コンテンツがない場合幅0になる
centerグリッドセル内の左右中央に配置し、コンテンツ幅はコンテンツに依存、高さはセルいっぱいに広がる ※コンテンツがない場合幅0になる

グリッドアイテム内のコンテンツは、HTMLに記述するテキストや画像などです。

グリッドアイテム内のコンテンツがない場合

画像のように、グリッドアイテム内にコンテンツがない場合、初期値の stretch 以外を指定すると、グリッドアイテム自体のが0となり、要素が表示されなくなります。(各アイテムにbackground-color指定していますが表示されていません)

strechはグリッドセル依存で大きさが確保されますが、それ以外のプロパティはコンテンツ依存の大きさとなるため、コンテンツがない=表示されなくなります。

<div class="grid-container">
  <div class="grid-item">item-1</div>
  <div class="grid-item">item-2</div>
  <div class="grid-item">item-3</div>
  <div class="grid-item">item-4</div>
  <div class="grid-item">item-5</div>
</div>
/* いずれかをグリッドコンテナに記述 */
justify-items: stretch; (初期値)
justify-items: start;
justify-items: end;
justify-items: center;

※画像はクリックすると拡大表示されます。

justify-items-stretch
justify-items: stretch;(初期値)
justify-items-start
justify-items: start;
justify-items-end
justify-items: end;
justify-items-center
justify-items: center;

align-items

align-itemsは、グリッドコンテナに記述することで、グリッドセル内上下方向の配置と、コンテンツの大きさを定義します。

セル内コンテンツへの効果
stretch(初期値)グリッドセルの領域全体にコンテンツが広がる
startグリッドセルの開始位置(上)に配置し、コンテンツ幅はセルいっぱいに広がり、高さはコンテンツ高さに依存する ※コンテンツがない場合幅0になる
endグリッドセルの終端位置(下)に配置し、コンテンツ幅はセルいっぱいに広がり、高さはコンテンツ高さに依存する ※コンテンツがない場合高さ0になる
centerグリッドセル内の上下中央に配置し、コンテンツ幅はセルいっぱいに広がり、高さはコンテンツ高さに依存する ※コンテンツがない場合高さ0になる

グリッドアイテム内のコンテンツは、HTMLに記述するテキストや画像などです。

justify-itemsでも説明した通り、グリッドアイテムのコンテンツがない場合、高さが0になることで要素が表示されなくなります。

<div class="grid-container">
  <div class="grid-item">item-1</div>
  <div class="grid-item">item-2</div>
  <div class="grid-item">item-3</div>
  <div class="grid-item">item-4</div>
  <div class="grid-item">item-5</div>
</div>
/* いずれかをグリッドコンテナに記述 */
align-items: stretch; (初期値)
align-items: start;
align-items: end;
align-items: center;

※画像はクリックすると拡大表示されます。

align-items-stretch
align-items: stretch;(初期値)
align-items-start
align-items: start;
align-items-end
align-items: end;
align-items-center
align-items: center;

グリッドセル内のコンテンツ位置・大きさを個別に指定

グリッドアイテムに記述することで、グリッドアイテム単体の配置や大きさを指定できるプロパティがあります。

justify-self

justify-selfは、グリッドアイテム個別に指定することで、セル内の水平方向に対する配置や大きさを調整できます。

セル内コンテンツへの効果
stretch(初期値)セル内いっぱいにコンテンツ領域が広がる
startセルの開始位置(左)に寄せる
endセルの終端位置(右)に寄せる
centerセル内の左右中央に寄せる
<div class="grid-container">
  <div class="grid-item center">center</div>
  <div class="grid-item start">start</div>
  <div class="grid-item end">end</div>
  <div class="grid-item">stretch</div>
  <div class="grid-item center">center</div>
  <div class="grid-item start">start</div>
  <div class="grid-item">stretch</div>
  <div class="grid-item end">end</div>
  <div class="grid-item center">center</div>
</div>
/* グリッドアイテム */
.center {
	justify-self: center;
}

/* グリッドアイテム */
.start {
	justify-self: start;
}

/* グリッドアイテム */
.end {
	justify-self: end;
}
justify-selfでグリッドアイテム単体の調整

align-self

align-selfは、グリッドアイテム個別に指定することで、セル内の垂直方向に対する配置や大きさを調整できます。

セル内コンテンツへの効果
stretch(初期値)セル内いっぱいにコンテンツ領域が広がる
startセルの開始位置(上)に寄せる
endセルの終端位置(下)に寄せる
centerセル内の上下中央に寄せる
<div class="grid-container">
  <div class="grid-item center">center</div>
  <div class="grid-item start">start</div>
  <div class="grid-item end">end</div>
  <div class="grid-item">stretch</div>
  <div class="grid-item center">center</div>
  <div class="grid-item start">start</div>
  <div class="grid-item">stretch</div>
  <div class="grid-item end">end</div>
  <div class="grid-item center">center</div>
</div>
/* グリッドアイテム */
.center {
	align-self: center;
}

/* グリッドアイテム */
.start {
	align-self: start;
}

/* グリッドアイテム */
.end {
	align-self: end;
}
align-selfでグリッドアイテム単体の調整

グリッドアイテムの並び方を変更

初期値だとグリッドアイテムは行方向(左から右)に並びますが、この並び順をコントロールできるプロパティを紹介します。

grid-auto-flow

グリッドコンテナにgrid-auto-flowを指定することで、グリッドアイテムの並び順を調整できます。

また、明示的に配置されていないグリッドアイテムも、grid-auto-flowで指定した方向に自動配置されます。

効果
row(初期値)グリッドアイテムが行方向から順に埋まる
columnグリッドアイテムが列方向から順に埋まる
/* グリッドコンテナに記述 */
grid-auto-flow: row; (初期値)
grid-auto-flow: column;

※画像はクリックすると拡大表示されます。

grid-auto-flow-row
grid-auto-flow: row; (初期値)
grid-auto-flow-column
grid-auto-flow: column;

また、明示的に配置されていないグリッドアイテム=空きスペースに対する配置ルールの値もあります。

効果
row dense空白のグリッドスペースがある場合、行方向に後続のコンテンツが埋め込まれるように自動配置される。
column dense空白のグリッドスペースがある場合、列方向に後続のコンテンツが埋め込まれるように自動配置される。

denseの意味は「密集」で、空白スペースがあった場合はそこを埋める指定ができます。

<div class="grid-container">
  <div class="grid-item item-1">item-1</div>
  <div class="grid-item item-2">item-2</div>
  <div class="grid-item item-3">item-3</div>
  <div class="grid-item item-4">item-4</div>
  <div class="grid-item item-5">item-5</div>
  <div class="grid-item item-6">item-6</div>
  <div class="grid-item item-7">item-7</div>
</div>
.grid-container {
	display: grid;
	grid-auto-flow: column;
	grid-template-columns: repeat(3, 150px);
	grid-template-rows: repeat(3, 100px);
}

/* 行番号3へ */
.item-2 {
	background-color: #f05656 !important;
	grid-row-start: 3;
}

/* 列番号2へ */
.item-5 {
	background-color: #f05656 !important;
	grid-column-start: 2;
}
grid-auto-flow:columnを指定

item-1とitem-5の位置を変更し、grid-auto-flowでcolumnを指定することで列方向(縦方向)に並び順を変更しています。

※グリッドアイテムの位置変更は、下の グリッドラインを基準にグリッドアイテムの位置を明示的に指定 で解説しています。(クリックするとスクロールします)

この時点では、画像のようにグリッドアイテムが配置されていない空白があります。

.grid-container {
	display: grid;
	grid-auto-flow: column dense;
	grid-template-columns: repeat(3, 150px);
	grid-template-rows: repeat(3, 100px);
}
grid-auto-flow: column denseを指定

grid-auto-flowの値をcolumn denseとすることで、空白を埋めるようにグリッドアイテムが配置されます。

グリッド間の余白を指定

gridレイアウトでは、marginを使わず要素間の余白をとることが可能です。

row-gap

row-gap はグリッド行間の余白を定義します。

/* row-gap: 余白サイズ */
row-gap: 50px;
row-gap

row-gap は、行方向のグリッドトラックに対して適用されます。

column-gap

column-gap は、グリッド列間の余白を定義します。

/* row-gap: 余白サイズ */
column-gap: 50px;
column-gap

column-gap は、列方向のグリッドトラックに対して適用されます。

gap

gap は column-gap と row-gap のショートハンドで、行と列間の余白を定義し、グリッドアイテムが隣接する箇所に適用されます。

/* gap: 余白サイズ */
gap: 50px;
gap

値をひとつ指定した場合、行方向と列方向のグリッドトラックに共通の余白を設けます。

/* gap: 行方向の余白サイズ 列方向の余白サイズ */
gap: 80px 40px;
gapのrowとcolumn一括指定

値を半角スペースで区切って指定すると、ひとつ目は行方向(row)、ふたつ目は列方向(column)に適用されます。

gapプロパティは、marginプロパティのように要素に適用されないため、余白がグリッドコンテナをはみ出すことはありません。

余白の調整が直感的に指定でき、デザイン次第ではコーディングも容易となります。

CSS Gridで使えるレスポンシブ対応の単位

CSS Gridには、リキッドレイアウトなどレスポンシブ対応にも有効な専用値があります。

fr

frはfraction(比率)のことで、gridで使える専用の値です。

grid-template-columns と grid-template-rows に指定することで、グリッドコンテナに合わせて余白を埋めるように自動でグリッドサイズを調整します。

/* 行の指定 */
grid-template-rows: 1fr 1fr 1fr;

/* 列の指定 */
grid-template-columns: 1fr 1fr;

画像のように、frの単位をつけたグリッドトラックは、グリッドコンテナの余白を埋めるように伸縮します。

1frの1という数値は伸縮倍率なので、2や3などと指定することも可能です。

grid-template-columns: 1fr 1fr 1fr
例:grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: 2fr 1fr 1fr
例:grid-template-columns: 2fr 1fr 1fr
grid-template-columns: 3fr 1fr 1fr
例:grid-template-columns: 3fr 1fr 1fr;
grid-template-columns: 3fr 2fr 1fr;
例:grid-template-columns: 3fr 2fr 1fr;
列や行の中で2つ以上fr単位を指定した場合

fr指定したトラックどうしで伸縮率が等分されます。

  • 1fr 1fr 1fr の場合:3列のグリッドトラックが3等分される
  • 3fr 1fr 1f の場合:3列のグリッドトラックが6:2:2で分配される

※ 3fr 1fr 1f の計算例

3(列A) + 1(列B) + 1(列C) = 5

列A:3 / 5 = 0.6( 60% )

列B:1 / 5 = 0.2( 20% )

列C:1 / 5 = 0.2( 20% )

グリッド構成を自動指定できる関数

CSS Grid Layoutでは、コンテナ領域のサイズやグリッドアイテムの大きさを計算し、自動的にグリッドを構成する独自の値があります。

FlexBoxなど他のCSSプロパティにはない便利な機能なので、使いこなせるようにしておきたいです。

repeat関数

repeat関数は、grid-template-columns と grid-template-rows の値として使える繰り返し関数です。

/* grid-template-xxx: (繰り返し回数 , セルサイズ)  */
grid-template-columns: repeat(3 , 1fr);
grid-template-rows: repeat(3 , 150px);

( )に内容を記述し、カンマ( , )で区切った左が繰り返す回数右の数値はグリッドサイズです。

上の場合、1fr(1/3)の列を3回、150pxの行を3回繰り返します。

repeat関数

グリット数を「繰り返し回数」とすることで、直感的にわかりやすく、記述もシンプルになります。


また、repeat関数も値のひとつであるため、半角スペースで区切ることでグリッド数を追加できます。

grid-template-columns: repeat(3 , 1fr) 2fr;
grid-template-rows: repeat(2 , 130px) 180px;
gap-repeatで値を半角区切り
  • columns:1〜3列目まで1fr(1/5)、4列目を2fr(2/5)
  • rows:1〜2行目まで130px、3行目を180px

複数セルまとめて制御することも可能です。

/* repeat(繰り返し関数 , サイズ1 サイズ2) */
grid-template-columns: repeat(2 , 150px 100px);
grid-template-rows: repeat(2 , 100px 150px);

繰り返し関数の後ろのサイズを、半角スペースで区切って記述します。

リピート関数内で繰り返し内容記述
  • columns:1列目150px→2列目100pxをワンセットとして2回繰り返し
  • rows:1行目100px→2行目150pxをワンセットとして2回繰り返し

auto-fill

auto-fillは、repeat関数の繰り返し回数として指定できる値です。

<div class="grid-container">
  <div class="grid-item">item-1</div>
  <div class="grid-item">item-2</div>
  <div class="grid-item">item-3</div>
  <div class="grid-item">item-4</div>
  <div class="grid-item">item-5</div>
  <div class="grid-item">item-6</div>
</div>
.grid-container {
	display: grid;
	grid-template-columns: repeat(auto-fill, 100px);
	grid-template-rows: repeat(3, 100px);
}

auto-fillを指定すると、画面幅を変えた時、グリッドコンテナにスペースがあっても自動的に空のグリッドが作られます。

HTMLの要素数(グリッドアイテム)がいくつあるかわからない、もしくは動的に可変するような場合など、あらかじめグリッド数(繰り返し数)を固定させたくない状況で役に立ちます。

auto-fit

auto-fitも、repeat関数で指定できる値で、自動的に繰り返し回数を計算して適用させます。

<div class="grid-container">
  <div class="grid-item">item-1</div>
  <div class="grid-item">item-2</div>
  <div class="grid-item">item-3</div>
  <div class="grid-item">item-4</div>
  <div class="grid-item">item-5</div>
  <div class="grid-item">item-6</div>
</div>
.grid-container {
	display: grid;
	grid-template-columns: repeat(auto-fit, 100px);
	grid-template-rows: repeat(3, 100px);
}

auto-fill と違い、グリッドコンテナ内のスペースに空のグリッドは生成されず、グリッドアイテムのサイズにフィットします。

minmax関数

minmaxは、要素の最小値と最大値を定義できる関数です。

/* minmax(min値 , max値) */
grid-template-columns: minmax(250px, 1fr) 100px 1fr;

()内をカンマで区切り、左に最小値、右に最大値を記述します。

.grid-container {
	display: grid;
	grid-template-columns: minmax(250px, 1fr) minmax(250px, 1fr) minmax(250px, 1fr);
	grid-template-rows: repeat(3, 150px);
}

上の動画でグリッドコンテナに記述しているコードです。minmax関数も値のひとつなので、上の場合3列固定のグリッド構成になります。

fr 指定しているため、画面幅が大きい時はコンテナ(画面幅)いっぱいまでセルが広がり続け、250pxまでなるとそれより小さくはなりません。

また、repeat関数と組み合わせることで、メディアクエリの記述をせずにレスポンシブ対応することも可能です。

画面幅に応じてカラム数が変化し、SPサイズでは1カラムになっています。

<div class="grid-container">
  <div class="grid-item">item-1</div>
  <div class="grid-item">item-2</div>
  <div class="grid-item">item-3</div>
  <div class="grid-item">item-4</div>
  <div class="grid-item">item-5</div>
  <div class="grid-item">item-6</div>
  <div class="grid-item">item-7</div>
  <div class="grid-item">item-8</div>
</div>
.grid-container {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
	grid-template-rows: repeat(8, 150px);
}

動画のレスポンシブ対応を実現しているコードです。

repeat関数のauto-fitで、グリッドコンテナ幅に応じたセルを自動生成しつつ、minmax関数でセルサイズも自動調整しています。

グリッド幅は1fr の適用により画面幅に応じて変動、250pxまで小さくなるたびにauto-fitのルールが適用し、グリッドコンテナ内で生成できるグリッド数が変化しています。

グリッドラインを基準にグリッドアイテムの位置を明示的に指定

ここまではグリッドコンテナの構成方法について解説してきましたが、次からはグリッドアイテムの指定について触れていきます。

グリッドアイテムは、grid-auto-flowのルールに従って順番に、規則的に並ばせるだけでなく、グリッドセル・トラックの中で自由に位置を調整できます。

また、隣り合うセルをまたいで、複数セルをひとつのグリッドアイテムとすることも可能です。

グリッドのライン番号とは?

CSSでグリッドを構成すると、自動的にグリッドライン番号が割り振られます。

グリッドのライン番号イメージ

ライン番号は検証ツールからも確認できます。

左上から、列のライン番号は右方向、行のライン番号は下方向に正数で1から順に増加し、右下からは列のライン番号が左方向、行のライン番号は上方向に負数で割り当てられます。

grid-row-start / grid-row-end / grid-column-start / grid-column-end

grid-row-startやgrid-row-endでは、グリッド行や列内におけるグリッドアイテムの先頭位置を指定できます。

プロパティ意味
grid-row-start方向:グリッド開始位置からカウント
grid-row-end方向:グリッド終了位置からカウント
grid-column-start方向:グリッド開始位置からカウント
grid-column-end方向:グリッド終了位置からカウント
/* グリッドアイテムに記述 */
grid-row-start: ライン番号;
grid-row-end: ライン番号;
grid-column-start: ライン番号;
grid-column-end: ライン番号;

値にはグリッドのライン番号を記述します。

<div class="grid-container">
  <div class="grid-item red">item-1</div>
  <div class="grid-item">item-2</div>
  <div class="grid-item">item-3</div>
  <div class="grid-item">item-4</div>
  <div class="grid-item">item-5</div>
  <div class="grid-item">item-6</div>
  <div class="grid-item">item-7</div>
  <div class="grid-item">item-8</div>
</div>
.red {
	background-color: red;
	grid-row-start: 3;
}
grid-row-startで指定

row-startは上からカウントし、指定したライン番号を基準にグリッドアイテムが移動します。


.red {
	background-color: red;
	grid-row-end: 3;
}
grid-row-endで指定

row-endは下からカウントし、指定したライン番号を基準にグリッドアイテムが移動します。


.red {
	background-color: red;
	grid-column-start: 3;
}
grid-column-startで指定

grid-column-startは左からカウントし、指定したライン番号を基準にグリッドアイテムが移動します。

※画像ではgrid-auto-flowを初期値のまま(row)にしているため、1つ目のグリッドアイテムの開始位置を変えることで、後続のグリッドアイテムもそのままズレるように移動しています。


.red {
	background-color: red;
	grid-column-end: 3;
}
grid-column-endで指定

grid-column-endは右からカウントし、指定したライン番号を基準にグリッドアイテムが移動します。


.red {
	background-color: red;
	grid-column-start: 2;
	grid-row-start: 2;
}
grid-row-startとgrid-column-startを同時に指定

column-startとrow-startを同時に指定することで、グリッドアイテムを縦横方向に移動させることも可能です。

grid-column / grid-row

grid-column や grid-row は、複数のグリッドセルをまとめることで、グリッドエリアとして指定できるプロパティです。

/* グリッドアイテムに記述 */
grid-row: ライン開始番号 / ライン終端番号;
grid-column: ライン開始番号 / ライン終端番号;

値はスラッシュ( / )で区切ってグリッドのライン番号を記述します。

スラッシュで区切ったライン番号は、左が開始位置で右が終端位置となります。

.red {
	background-color: red;
	grid-row: 1 / 3;
}
grid-rowで指定

上の場合、行に対して開始位置が1番、終端位置は3番を指定しています。


.red {
	background-color: red;
	grid-column: 1 / 4;
}
grid-columnで指定

grid-columnでは列方向に1番から4番までをグリッドエリアとして指定しています。

span

値に span を使用することで、ライン番号ではなく「グリッドトラックを伸ばす数」として指定できます。

/* グリッドアイテムに記述 */
grid-row: ライン番号 / span 伸ばしたいトラック数;
grid-column: ライン番号 / span 伸ばしたいトラック数;

spanの後ろに半角スペースを空け、伸ばしたいトラックス数を記述します。span はその性質上スラッシュの後ろの大きい数字で使用します。

<div class="grid-container">
  <div class="grid-item red">item-1</div>
  <div class="grid-item">item-2</div>
  <div class="grid-item">item-3</div>
  <div class="grid-item orange">item-4</div>
  <div class="grid-item">item-5</div>
  <div class="grid-item">item-6</div>
  <div class="grid-item">item-7</div>
  <div class="grid-item">item-8</div>
  <div class="grid-item">item-9</div>
</div>
/* 3列 3行のグリッドコンテナ */
.grid-container {
	display: grid;
	grid-template-columns: repeat(3 , 150px);
	grid-template-rows: repeat(3, 100px);
}

/* グリッドアイテム1 */
.red {
	background-color: red;
	grid-column: 1 / span 3;
}

/* グリッドアイテム2 */
.orange {
	background-color: orange;
	grid-row: 2 / span 2;
}
gridアイテムをspanで指定

redクラス(item-1)はgrid-columnで、列のライン番号1から3つ分トラックを伸ばしています。※ grid-column: 1 / 4 と同じ

orangeクラス(item-4)はgrid-rowで、行のライン番号2から2つ分トラックを伸ばしています。 ※ grid-row: 2 / 4 と同じ

Z-indexで重なりを制御

グリッドアイテムの位置が重なるような指定をした場合、ブラウザ上でも重なって表示されます。

<div class="grid-container">
  <div class="grid-item item1">item-1</div>
  <div class="grid-item item2">item-2</div>
  <div class="grid-item">item-3</div>
  <div class="grid-item">item-4</div>
  <div class="grid-item">item-5</div>
  <div class="grid-item">item-6</div>
  <div class="grid-item">item-7</div>
  <div class="grid-item">item-8</div>
  <div class="grid-item">item-9</div>
</div>
.grid-container {
	display: grid;
	grid-template-columns: repeat(3, 150px);
	grid-template-rows: repeat(3, 100px);
}

.item1 {
	background-color: DarkBlue !important;
	grid-column: 1 / span 3;
	grid-row: 1 / span 2;
}

.item2 {
	background-color: Maroon !important;
	grid-column: 1 / span 2;
	grid-row: 2 / span 2;
}
z-index指定前

上のように grid-column と grid-row の指定値が被っていると、HTMLの記述順で上に重なって表示されます。

.item1 {
	background-color: DarkBlue !important;
	grid-column: 1 / span 3;
	grid-row: 1 / span 2;
	z-index: 2;
}

.item2 {
	background-color: Maroon !important;
	grid-column: 1 / span 2;
	grid-row: 2 / span 2;
}
z-index指定後

z-index の数値を変えることで、重なり順が変更されました。

グリッドアイテムを配置する順番を変える

グリッドアイテムは、HTML(DOM)を上から順に読み込み、順番に配置されていきます。

この並び順は、個別の指定が可能です。

order

orderはFlexboxでも使用されますが、コンテナ内における要素の並び順を個別で指定できるプロパティです。

order: コンテナ内グリッドアイテムの順番;

orderの値は整数で、グリッドセル数の中から1以降の数値で指定します。

未指定の初期値は0で、0を指定した場合はHTMLの順番通り、初期位置に配置されます。

CSS Gridにおけるorderは、orderプロパティを指定した要素の中で順序が変わります。

<div class="grid-container">
  <div class="grid-item item-1">item-1</div>
  <div class="grid-item item-2">item-2</div>
  <div class="grid-item item-3">item-3</div>
  <div class="grid-item item-4">item-4</div>
  <div class="grid-item item-5">item-5</div>
  <div class="grid-item item-6">item-6</div>
  <div class="grid-item item-7">item-7</div>
  <div class="grid-item item-8">item-8</div>
  <div class="grid-item item-9">item-9</div>
</div>
グリッドレイアウト画像

上記のグリッドレイアウトに対してorderを指定します。

.item-1 {
	background-color: #a1a9c0;
	order: 1;
}
1箇所order指定

item-1クラスにorder:1を指定したところ、一番後列の右下に移動しました。これはグリッドアイテム内でorder を指定しているのがitem-1クラスのみだからです。

他要素はすべて、order: 0 の初期値が適用されているため、最後尾のitem-9クラス(order: 0)の次に順番がうつっています。

.item-1 {
	background-color: #a1a9c0;
	order: 2;
}

.item-3 {
	background-color: #c0b3a1;
	order: 1;
}

.item-5 {
	background-color: #a1bac0;
	order: 3;
}
3箇所order指定

次にitem-1、item-3、item-5クラスにそれぞれorder指定しました。元の順番(HTMLの順番)を無視し、order番号通りに並んでいることがわかります。

もし異なるグリッドアイテムに同じorder番号を指定した場合、元の順番(HTMLの順番)に従って優先順位がつけられ、並び直します。

グリッドエリアに名前をつけて配置

グリッドのライン番号でグリッドアイテムの位置を指定すると、直感的にどこを指しているのかわかりにくいという難点があります。

しかし、セルに任意の名前をつけて、アイテムの位置を管理できる便利な機能もあります。

  • grid-template-areas:グリッドトラックにエリア名をつける。グリッドコンテナに指定。
  • gird-area:グリッドアイテムの位置や大きさを、エリア名の場所に指定。

grid-template-areas と grid-area はセットで使います。

grid-template-areas

/* グリッドコンテナに記述 */
grid-template-areas: "エリア名";

grid-template-areasは任意の名前をダブルクォーテーション(”)で囲みます。名前は半角スペースで区切って複数記述でき、記述した数が列数となります。

grid-template-areas: "a a a";

上の場合、「a」という名前で、3列のグリッドが構成されます。

grid-template-areas: 
  "a a a a"
  "b b b b"
  "c c c c";

また、名前を改行して複数記述することで、グリッドの行数を指定することも可能。最後の名前行にだけセミコロン( ; )をつけます。

上の場合だと、名前「a」の行を4列、名前「b」の行を4列、名前「c」の行を4列、4列 × 3行のグリッドが構成されます。

grid-area

グリッドコンテナで指定したエリア名をグリッドアイテムで指定します。

/* グリッドアイテムに記述 */
grid-area: エリア名;

プロパティ名はgrid-areaで、値にはエリア名を書きます。grid-template-areasとは異なり、エリア名ダブルクォーテーション(”)で囲む必要はありません。

.grid-item1 {
	grid-area: a;
}

.grid-item2 {
	grid-area: b;
}

.grid-item3 {
	grid-area: c;
}

各グリッドアイテムに対し、grid-areaでエリア名を指定します。

grid-template-areasとgrid-areaを組み合わせる

<div class="grid-container">
  <div class="grid-item header">header</div>
  <div class="grid-item main">main</div>
  <div class="grid-item side">side</div>
  <div class="grid-item footer">footer</div>
</div>
/* グリッドコンテナ */
.grid-container {
	display: grid;
	grid-template-areas: 
   "header header header"
	"main main side"
	"main main side"
	"footer footer footer";
}

/* グリッドアイテム */
.grid-item {
	padding: 50px;
}

grid-template-areasのエリア名で、グリッドトラックを指定した3列 × 3行になるグリッドコンテナを作っています。

grid-area指定前
grid-area指定前

グリッドアイテムにgrid-areaを指定する前の状態です。

この段階ではグリッド位置を指定していないため、暗黙的なグリッドセルしか構成されていません。

※アイテムにpaddingを指定して大きさを確保しているため、HTMLの要素分(4つ)だけは表示されています。

/* グリッドコンテナ */
.grid-container {
	display: grid;
	grid-template-areas: 
   "header header header"
	"main main side"
	"main main side"
	"footer footer footer";
}

.grid-item {
	color: #fff;
	font-size: 1.4em;
	padding: 50px;
}

/* 各グリッドアイテム */
.header {
	background-color: DarkBlue;
	grid-area: header;
}

.main {
	background-color: Brown;
	grid-area: main;
}

.side {
	background-color: pink;
	grid-area: side;
}

.footer {
	background-color: SlateGray;
	grid-area: footer;
}
grid-template-areasで位置指定

各アイテムにgrid-areaでエリア名を指定したことで、画像のようにグリッドエリアができます。

グリッドラインの番号からもわかるように、mainやsideは指定した通り2行分の領域を確保しています。

.grid-container {
	display: grid;
	grid-template-areas: 
   "header header"
	"main main side"
	"main main side"
	"footer footer footer";
}

なお、グリッドエリア名で構成するグリッドは四角形でなければいけません。

上のコードではheaderエリアの指定が2列分しかなく、他の行と列数が異なるため四角形が構成されず、画像のようにエラーとなります。

グリッドエリアの数が不足していることでエラーになる

grid-template-areasでエラーが出た場合、グリッドアイテムが重なってしまい、グリッド構成自体が指定通りに効きません。

(実践)簡単なデザインの実装例

CSS Gridで作るかんたんなカード型レイアウトのコードをご紹介します。

CSS Gridで作るカード型レイアウトのデモ
<div class="container">
  <div class="grid_item">
    <p class="img"><img src="penguin.jpg" alt=""></p>
    <div class="text">
      <h3>ダミータイトル</h3>
      <p>ダミーダミーダミーダミーダミーダミー</p>
    </div>
  </div>
  <div class="grid_item">
    <p class="img"><img src="penguin.jpg" alt=""></p>
    <div class="text">
      <h3>ダミータイトル</h3>
      <p>ダミーダミーダミーダミーダミーダミー</p>
    </div>
  </div>
  <div class="grid_item">
    <p class="img"><img src="penguin.jpg" alt=""></p>
    <div class="text">
      <h3>ダミータイトル</h3>
      <p>ダミーダミーダミーダミーダミーダミー</p>
    </div>
  </div>
  <div class="grid_item">
    <p class="img"><img src="penguin.jpg" alt=""></p>
    <div class="text">
      <h3>ダミータイトル</h3>
      <p>ダミーダミーダミーダミーダミーダミー</p>
    </div>
  </div>
  <div class="grid_item">
    <p class="img"><img src="penguin.jpg" alt=""></p>
    <div class="text">
      <h3>ダミータイトル</h3>
      <p>ダミーダミーダミーダミーダミーダミー</p>
    </div>
  </div>
  <div class="grid_item">
    <p class="img"><img src="penguin.jpg" alt=""></p>
    <div class="text">
      <h3>ダミータイトル</h3>
      <p>ダミーダミーダミーダミーダミーダミー</p>
    </div>
  </div>
  <div class="grid_item">
    <p class="img"><img src="penguin.jpg" alt=""></p>
    <div class="text">
      <h3>ダミータイトル</h3>
      <p>ダミーダミーダミーダミーダミーダミー</p>
    </div>
  </div>
  <div class="grid_item">
    <p class="img"><img src="penguin.jpg" alt=""></p>
    <div class="text">
      <h3>ダミータイトル</h3>
      <p>ダミーダミーダミーダミーダミーダミー</p>
    </div>
  </div>
</div>
/* リセットCSS */
* , ::before , ::after {
	box-sizing: border-box;
	list-style: none;
	margin: 0;
	padding: 0;
}
/***********************/

.container {
	display: grid;
	gap: 20px;
	grid-template-columns: repeat(auto-fill, 300px);
	grid-template-rows: repeat(3, 300px);
	justify-content: center;
	margin: 20px auto;
	max-width: 1200px;
	padding: 20px;
}

.grid_item {
	box-shadow: 4px 4px 0 rgba(0, 0, 0, .09);
}

.img {
	height: 200px;
	text-align: center;
}

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

.text {
	padding: 10px;
}

レイアウト自体はコンテナ要素(containerクラス)だけで完結しています。

動画の通り、画面幅の可変に応じてカラムも変わっていますがメディアクエリは使用していません。

justify-content: centerで左右中央に配置、画面幅に応じてカラム数が切り替わるよう、repeat関数とauto-fillを使っています。(max-widthの指定で3列以上には広がらないようにしています)

カード間の余白も、gapプロパティを1行指定しているだけです。

Flexboxとの違い

  1. 親要素にdisplayプロパティを指定しコンテナ化
  2. 自動的に子要素を整列させる

CSS GridとFlexbox、基本的な仕組みは同じですが、指定できる軸方向の数に違いがあります。

FlexBoxはコンテナ要素に対し、水平か垂直どちらか1方向の軸を基準に子要素(フレックスアイテム)が整列します。

それに対し、CSS Gridは当記事でも解説している通り、縦横2方向の軸で構成されたグリッドに沿って子要素(グリッドアイテム)が配置されます。

.grid-container {
	display: flex;
	flex-wrap: wrap;
	max-width: 450px;
}

.grid-item {
	flex-basis: 150px;
	height: 100px;
}
1方向の軸を基準に整列するFlexboxのイメージ
Flexbox

Flexboxで2行以上にわたって要素を並べる場合、コンテナ要素に最大幅を指定したうえで、flex-wrap: wrapで折り返させる必要があります。

「子要素の幅 × 子要素の数 = 子要素全体の幅」と「コンテナ幅」の大小関係で、表示されるカラム数が変わることを意識したコーディングが必要になります。

.grid-container {
	display: grid;
	grid-template-columns: repeat(3, 150px);
	grid-template-rows: repeat(3, 100px);
}
2軸方向で構成されるイメージ
CSS Grid

それに対してGridの場合、親要素へ列数と行数を指定するだけで、複数行のレイアウトが完成します。

画像のようなデザインであれば、CSS Gridのほうが簡単にコーディングできることがわかるかと思います。

CSS Gridのジェネレーター紹介

GridをGUIで作れる便利なジェネレーターを紹介します。

基礎的な知識を身につけたうえで使用すると、より理解が深まるでしょう。

Interactive CSS Grid Generato

Interactive CSS Grid Generatoキャプチャ

grid-template-areasのエリア名まで指定できる多機能なジェネレーターです。

cssgr.id

cssgr.idのキャプチャ

シンプルな操作性が特徴のジェネレータです。右サイドバーのStarter Layoutsから、いくつかのレイアウトサンプルを選択できます。

CSS Gridのチートシート紹介

当記事で解説した内容でコードの理解を深めたうえで、視覚的にサクッとチェックしたい場合、チートシートで確認することがオススメです。

GRID: A simple visual cheatsheet for CSS Grid Layout

simple visual cheatsheet for CSS Grid Layoutのキャプチャ

プロパティとレイアウトイメージがセットで確認できるチートシートです。

Grid by Example

Grid by Exampleのキャプチャ

さまざまなレイアウトパターンが確認でき、View exampleを開くとCODE PENが開かれコードまで確認できます。

まとめ

グリッドレイアウトとは?
縦横方向のラインで構成されるグリッドを用いて、格子状のエリアに要素を配置するレイアウト
グリッドレイアウトでコーディングはどう変わる?
メディアクエリでの細かい指定が省略できたり、アイテム間の余白管理が容易になることで、コーディング速度を上げられるケースが増える
どんなデザイン構築に便利?
縦横2軸で構成でき、コンテナや各アイテムが四角形で構成されるレイアウト

アイテムやコンテナの形が四角形で構成されないレイアウトの場合や、1方向(横並びなど)のレイアウトであれば、わざわざグリッドレイアウトを使う必要はありません。

しかし、2軸方向で構成されたデザインであれば、シンプルかつ直感的にわかりやすいCSS Gridを採用するシーンは今後増えてくるでしょう。

そのときは、当記事を参考にしていただけると嬉しいです!