備忘録的プログラミングリファレンス

display: grid; の使い方

 display: grid; を用いた段組みレイアウトの作成とその調整方法についての解説です。

 display: grid; は、エレメントを横、縦に整然と並べるといった web ページのレイアウトに利用できる CSS のプロパティです。

表示例

 ページのレイアウトにおいてカラム分割などと呼ばれます。

 display: grid; でレイアウトを作成する場合の注意点としては、事前にレイアウトの形を想定しておく必要があります。レイアウトを事前に想定しておくことについては配置の基本を参照してください。

 表示幅によってレイアウトを変更する横スクロールで一覧を表示するには display: flex; を参照してください。

配置の基本

 display: grid; では以下のような表示基準が設けられています。この表示基準に基づき、grid-templategrid-template-areasgrid-template-columnsgrid-template-rows といった関連プロパティによってエレメントの並び方を指定することができます。

1234→main axis(主軸)
1
2
3
4
cross axis(交差軸)

 画像やエレメントはデフォルトでは縦に順次並びますが、display: grid; はそれらを縦横に並べることができます。

 display: grid; でレイアウトを作成する際は事前にどのようなレイアウトを作成するかを決めておくことをお勧めします。

 まず、上記のように m ✕ n のマス目を想定し、そのマス目において各エレメントの位置と領域を決めます。

 詳しくはgrid-areaを参照してください。

display: grid;による効果

 display: grid; のみの設定では何も起こらず、display プロパティで grid や flex を指定していない場合と同じように表示されます。

 例えば、以下のようにcontenaエレメントが3つのgrid_item01grid_item02grid_item02 エレメントを包括しているとします。

<div class="contena">
	<div class="item a"> grid_item01 </div>
	<div class="item b"> grid_item02 </div>
	<div class="item c"> grid_item03 </div>
	<div class="item d"> grid_item04 </div>
	<div class="item e"> grid_item05 </div>
	<div class="item f"> grid_item06 </div>
</div>

<style>
.contena {
	display: grid;

	border: 1px solid gray;
}

.item{
	border:1px solid gray;
}
</style>

border は分かりやすく表示されるように設定してあります。

 display: grid; のみを設定している場合は以下のように表示されます。

grid-template-columns や grid-template-rows の設定

 次に、主軸方向(横方向)の並びである grid-template-columns や、交差軸方向(縦方向)を指定する grid-template-rows を設定してみます。

.contena {
	display: grid;
	grid-template-columns: 100px 100px 100px;
	grid-template-rows: 100px 100px;

	border: 1px solid gray;
	overflow: hidden;
	resize: both;
}

borderoverflowresize は分かりやすく表示されるように設定してあります。

 以下のように横並びで表示されます。display: grid; によって上記の縦に並んだアイテムを縦横に並べることができます。

 contenaエレメントをグリッドコンテナ、子エレメントであるgrid_item01grid_item02grid_item02 エレメントグリッドアイテムと呼びます。

 display: grid; において、grid-template-columns は主軸方向(横)に並べるグリッドアイテムの数とその幅の指定です。
 grid-template-rows は交差軸(縦)に並べるアイテムの数とその高さの指定です。

auto、 1fr 値

 grid-template-columnsgrid-template-rows で auto 値または 1fr 値を使用することで残りの大きさという意味の指定ができます。

.contena {
	display: grid;
	grid-template-columns: 150px auto 150px;
	grid-template-rows: 100px 300px;

	border: 1px solid gray;
	overflow: hidden;
	resize: both;
}

borderoverflowresize プロパティは分かりやすく表示されるように設定しています。

 1段めの真ん中を auto 値で指定ししています。

 以下のように真ん中の領域が幅の残り分になります。全体の大きさを変えると真ん中の幅のみが変化します。

 グリッドアイテムを連結したい場合があります。正確には、グリッドにおいて連結という機能がなく、区割りを指定することで表示領域を指定します。

 グリッドアイテムの配置と区切りを指定する方法には他に、

grid-area

 アイテムを連結したようにみせる区割りは grid-area で指定することができます。

 grid-area には名称を付ける機能の他に、配置位置と区切りを指定することができます。

  grid-area の指定は、[ grid-row-start / grid-column-start / grid-row-end / grid-column-end ] です。
 連結という意味で行方向(交差軸方向)、列方向(主軸方向)の区割りを指定することができます。ここでは、実際にはエレメントを連結するのではなく1つのエレメントの区切りを変更するために区切りと表現しています。

 grid-area プロパティは個々のエレメントで指定します。例えば、1段めを列方向(主軸方向)に3つ分またいだ形にするには、auto /span 3と指定します。

.contena {
	display: grid;
	grid-template-columns: 150px 1fr 150px;
	grid-template-rows: 100px 300px;

	overflow: hidden;
	resize: both;
	border: 1px solid gray;
}

.item {
	border:1px solid gray;
}

.a {
	grid-area: auto /span 3;
}

borderoverflowresize プロパティは分かりやすく表示されるように設定しています。

 上記のコードは以下のようになります。

 上記の例から分かるように、エレメントを連結表示(区割りを変更)することで、grid_item05、grid_item06 はズレてきたことが分かります。grid_item06 の右隣は空いていますが、n ✕ m のようなマス目の指定であることが期待されるためです。
 display: grid; でレイアウトを作成する場合は、事前にレイアウトの形を想定しておく必要があることが分かります。

 グリッドアイテムの配置と区切りを指定する方法には他に、grid-columngrid-row があります。
 さらに、細かく指定や変更を行うには、grid-column-endgrid-column-startgrid-row-endgrid-row-start を使用します。

grid-area と grid-template-areas

 レイアウトを指定する方法に、各エレメントに grid-area によって名称を付けて、grid-template-areas プロパティでそれらの名称からレイアウトを指定する方法があります。

  grid-area を各フレックスアイテムに、フレックスコンテナで grid-template-areas プロパティを指定します。

.contena {
	display: grid;
	grid-template-areas: 'a a a' 'b c d' 'e f .';

	overflow: hidden;
	resize: horizontal;
	border: 1px solid gray;
}

.a {
	grid-area: a;
}

.b{
	grid-area: b;
}

.c{
	grid-area: c;
}

.d{
	grid-area: d;
}

.e{
	grid-area: e;
}

.f{
	grid-area: f;
}

borderoverflowresize プロパティは分かりやすく表示されるように設定しています。

 この設定は以下のように表示されます。

 主軸方向(横方向)に並べるエレメントを指定します。
 上記の例のように、n ✕ m のようなマス目の指定であることが期待されます。そのために、存在しないエレメントは.で代用します。
 同じ名称は連結されたような形で表示されます。

grid-area と grid-template-areas におけるアイテムの大きさ

  grid-areagrid-template-areas プロパティにおいてグリッドアイテム大きさを指定する方法に

 grid-auto-columns はグリッドアイテムの統一した幅を、grid-auto-rows は高さを指定できます。これらはグリッドコンテナに指定します。

.contena {
	display: grid;
	grid-template-areas: 'a a a' 'b c d' 'e f .';
	grid-auto-columns: 100px 1fr 100px;
	grid-auto-rows: 100px 300px 150px;

	overflow: hidden;
	resize: horizontal;
	border: 1px solid gray;
}

.a {
	grid-area: a;
}

.b{
	grid-area: b;
}

.c{
	grid-area: c;
}

.d{
	grid-area: d;
}

.e{
	grid-area: e;
}

.f{
	grid-area: f;
}

空いた部分を埋めるには

 上記の例では grid_item06 の右隣が空いています。これを埋めるには、grid_item06 と右の空白部分を連結する方法があります。
 連結するには、アイテムごとで grid-column を使用して連結する方法があります。
 grid-area で指定する方法もありますが、grid-template-areas プロパティを使用した方法では難解になりますのでここでは取り上げません。

.contena {
	display: grid;
	grid-template-areas: 'a a a' 'b c d' 'e f .';
	grid-auto-columns: 100px 1fr 100px;
	grid-auto-rows: 100px 300px 150px;

	overflow: hidden;
	resize: horizontal;
	border: 1px solid gray;
}

.a {
	grid-area: a;
}

.b{
	grid-area: b;
}

.c{
	grid-area: c;
}

.d{
	grid-area: d;
}

.e{
	grid-area: e;
}

.f{
	grid-area: f;
	grid-column: span 2;
}

borderoverflowresize プロパティは分かりやすく表示されるように設定しています。

 grid_item06 に該当する f クラスのエレメントで grid-column: span 2; を指定しています。以下のように表示されます。

 もしも grid_item06 の右隣にエレメントが存在していたら、連結することでそのエレメントはさらにズレて表示されます。

grid-template

 grid-template によって一括してグリッドレイアウトを設定する方法もあります。

 上記のgrid-area と grid-template-areasのようなレイアウトを grid-template で設定するには以下のようにします。

.contena {
	display: grid;
	grid-template: "a a a" 100px
 		"b c d" 300px
		"e f ." 100px / 100px 1fr 100px;

	overflow: hidden;
	resize: horizontal;
	border: 1px solid gray;
}

.a {
	grid-area: a;
}

.b{
	grid-area: b;
}

.c{
	grid-area: c;
}

.d{
	grid-area: d;
}

.e{
	grid-area: e;
}

.f{
	grid-area: f;
}

borderoverflowresize プロパティは分かりやすく表示されるように設定しています。

 grid-template は、grid-template-areasgrid-auto-columnsgrid-auto-rows を組み合わせたような使い方ができます。

アイテム間の間隔

 グリッドアイテム間の間隔を変更するには、grid-gapgrid-row-gapgrid-column-gap を使用します。

.contena {
	display: grid;
	grid-template: 100px 300px 100px / 100px 1fr 100px;
	grid-gap: 10px 5px;

	overflow: hidden;
	resize: horizontal;
	border: 1px solid gray;
}

 grid-gap はエレメント周りの空白は作成しないようです。

 grid-gap は高さ方向、幅方向の間隔を一括で指定できます。各々を指定するには、grid-row-gapgrid-column-gap を使用します。

グリッドアイテムの配列

 グリッドアイテムの配列はスマートフォン、タブレット、PCといった表示デバイスによって変更したい場合があります。
 例えば、表示幅によってアイテムが横に並ぶ数を変更したい場合などです。
 グリッドレイアウトにおいて、表示幅によってアイテムの並びを変更するには grid-template-columns プロパティの値に repeat() を使用します。

.contena {
	display: grid;
	grid-template-columns: repeat( auto-fill, 100px );
	grid-auto-rows: 100px;
	grid-gap: 10px;
	padding: 10px;

	overflow: hidden;
	resize: both;
	border: 1px solid gray;
}

.item {
	border:1px solid gray;
}

グリッドアイテムの配置位置と大きさ

 グリッドアイテムの配置位置や大きさは変更することができます。

 以下の例は 4 ✕ 3 のマス目を想定してそれぞれのアイテムの位置と領域を変えています。

.contena {
	display: grid;
	grid-template-areas: 'a a c d' 'a a b b' 'e f b b';
	grid-auto-columns: 1fr 20% 20% 20%;
	grid-auto-rows: 150px 150px 150px;

	overflow: hidden;
	resize: both;
	border: 1px solid gray;
}

.a {
	grid-area: a;
}

.b{
	grid-area: b;
}

.c{
	grid-area: c;
}

.d{
	grid-area: d;
}

.e{
	grid-area: e;
}

.f{
	grid-area: f;
}