ウミ
クル

Grid Layoutのチートシートと使い方

縦と横の二次元レイアウトに便利なGrid Layoutについて説明します。
まずはチートシートをご覧ください。

Grid Layoutチートシート

チートシートの見方

チートシートの右上はグリッドの用語説明、左側は親要素に設定するプロパティ、右下は子要素に設定するプロパティの説明になります。
手型のアイコンはショートハンドプロパティを示しています。

① 親要素をグリッドコンテナとして指定する。

display: grid;
見た目に変化はありませんが、全ての直接の子要素がグリッドアイテムとなり、自動的に行が作成されます。
position: fixed; または absolute; で指定された子要素はグリッドアイテムにはならない)

②-1 行と列の数が明確な場合の指定方法(明示的グリッド)

あらかじめ行と列の数がわかっている場合は、数とサイズを以下のプロパティで指定します。

grid-template-rows:
grid-template-columns:
行(row)、列(column)に対して数とサイズを指定(半角スペースで区切る)。
チートシートでは、50pxの行を4行、100pxの列を3列、つまり4 x 3のグリッドを作ると指定しています。
ライン名を指定する場合はサイズ値の前後に任意の名前を[ ]にて設定します。
[row1-start] 50px [row1-end row2- start] 50px [row2-end row3-start] 50px [row3-end] 50px [line5];

grid-template-areas:
各セルに対して任意の名前を設定し、“” で囲んで列を、改行にて行を指定します。
チートシートでは、一行目の全3セルをheader、2、3行目の1、2列をmainと指定。 これにより1行目はheaderというエリアに、その下の4つのセルをmainというエリアに指定することができます。 セルに名前をつけない場合は .(ドット)でセルの場所を指定。

grid-template:
grid-template-rows:grid-template-columns: のショートハンドとして、行と列のサイズ指定をします。 ここにさらに grid-template-areas: を加えてエリアの名前を同時に指定することもできます。

明示的グリッド

②-2 行と列の数が不明確な場合は自動配置の方法を指定する
(暗黙的グリッド)

指定した明示的グリッドに、グリッドアイテムの数が収まらずはみ出した場合や、 JavaScriptなどを使ってサーバーからコンテンツを取得するなど、 グリッドアイテムの数が不明な場合にはこちらのプロパティで自動配置の方法を指定します。

grid-auto-rows:
grid-auto-columns:
自動で作成される行や列に対するサイズの指定。

grid-auto-flow:
行を自動作成するのか、列を自動作成するのかを決める指定。
明示的に位置を指定しない場合は、アルゴリズムに基づいてアイテムが自動配置されますが、 場合によっては空白のセルが発生する場合があります (グリッドの一部に複数セルを利用したエリアが明示的に設定されている場合など)。
その場合にはdense(密集)を指定すると、配置順が変更され空白のセルが発生しません。

暗黙的グリッド

grid:
明示的グリッドプロパティ、暗黙的グリッドプロパティとしてあげた上記全てのショートハンドで、書き順は次のとおり。
rowの指定 / columnの指定;
チートシートにある auto-flow 50px / 100px 100px 100px;
「50pxの行を必要な分だけ、100pxの列を3列作成する」という指定になります。

③ グリッドアイテムの位置を指定する

①②で出来上がったグリッドに以下のプロパティで子要素を配置します。

grid-row: 2 / 4;
値にライン番号を指定することにより、行の開始と終了を指定。
行のライン番号2から4まで。(フッターなど最終行に配置する場合は -2 / -1と指定すると、行数が途中で増えてもメンテが楽)

grid-row: 2 / span 2;
隣接するトラックを複数使ったエリアを指定する場合は span も使えます。
行のライン番号2から2つの連続するトラック(grid-row: 2 / 4; と同じ意味)。

grid-row: row2-start / row3-end;
②でライン名を設定した場合はライン名を指定することも可能([ ]は記入しない)。

grid-area:
grid-row:grid-column: のショートハンド。記入の順序がややこしいので要注意。
grid-row-start / grid-column-start / grid-row-end / grid-column-end;
grid-template-areas: を指定した場合はエリア名での指定も可能。

グリッドアイテム指定

各要素の位置やサイズを調整して完成

各プロパティに対する指定可能な値についてはチートシートの各項目を参照してください。

親要素に設定するプロパティ

grid-row-gap: 行間の余白のサイズ
grid-column-gap: 列間の余白のサイズ
grid-gap: grid-row-gap:grid-column-gap: のショートハンド
align-content: 垂直方向における親要素(コンテナ)の位置指定
justify-content: 水平方向における親要素(コンテナ)の位置指定
place-content: align-content:justify-content: のショートハンド
align-items: 垂直方向における子要素(アイテム)の位置指定
justify-items: 水平方向における子要素(アイテム)の位置指定
place-items: align-items:justify-items: のショートハンド

各子要素に設定するプロパティ

align-self: 垂直方向における各子要素の位置指定
justify-self: 水平方向における各子要素の位置指定
place-self: align-self:justify-self: のショートハンド
z-index: 子要素同士の重なりの順序指定
order: 順序の指定

以下は補足情報です。

サイズ指定のプロパティに使える値について

fr
サイズの指定にはpxや%などなんでも使えますが、新しい単位 fr がとても便利です。
fr(フラクショナルユニット)は利用可能な幅に対して均等に分割するための単位で、ブラウザの幅が変わっても指定した比率でサイズが計算されるため、レスポンシブな単位です。
(各コンテンツ幅以下には小さくならない、つまり各コンテンツ幅がバラバラな場合で十分な利用幅がない場合は等分にならないので注意)

grid-template-columns: 1fr 2fr 1fr;
比率 1 : 2 : 1の指定

コンテナ幅が 1000px で、gap: 50px; の場合の例:
grid-template-columns: 50% 1fr 1fr;
1列目=500px(%はgapを含めず純粋にコンテナ幅からの計算)
2列目=200px(残り500pxからgap2本分を引いた幅を二等分した値)
3列目=200px(残り500pxからgap2本分を引いた幅を二等分した値)

min-content
コンテンツ内の最大の単語幅を元に改行して、最小に表示。

max-content
改行せず、コンテンツの幅で表示。
コンテンツの幅が増えれば合わせて調整してくれる。

minmax(50px 100px)
50pxと100pxの間の指定。表示幅に余裕があればmax値(100px)、余裕がない場合はmin値(50px)までレスポンシブに対応する。

repeat(4, 50px)
50pxを4回繰り返すという指定。
50px 50px 50px 50px;の代わりにコンパクトに記述できる。

repeat(2, 50px) 100px;
repeat を一部分のみ使うことも可能。

repeat(5, 1fr 2fr);
1fr トラックに 2fr トラックが続くパターンを5回繰り返した全10トラックを表現する方法。

repeat(3, [col-start] 1fr [col-end]) 200px [grid-end];
repeatを使ったときのライン名は、上記の位置に入れます。
名前を[-start][-end]で指定すると自動で、連続番号[ 1]が以下のように付与されます。
[col-start 1] 1fr [col-end 1 col-start 2] 1fr [col-end 2 col-start 3] 1fr [col-end 3] 200px [grid-end];

repeat(auto-fill, 50px);
50pxのトラックが入るだけ入る指定。
コンテナ幅に余裕があれば余白が生まれます。

repeat(auto-fit, 50px);
50pxのトラックが入るだけ入る指定。
コンテナ幅に余裕があっても余白は残さず、コンテンツのないトラックの幅は0になります。

grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
200px以上の列が入るだけ入り、デバイス幅が小さくなれば列数が減り新たな行が生まれます。
auto-fit や minmax を駆使するとメディアクエリを使わなくてもレスポンシブ対応が可能です。

ライン名について

grid-template-areas に設定していない名前でも、grid-template-columns/rows にてライン名を[-start/-end]で設定していれば、grid-areaで使えます。

grid-template-columns: [hd-start] 1fr 1fr 1fr [hd-end];
grid-area: hd;

グリッドアイテムをさらにグリッドコンテナにしたり、グリッドアイテムをフレックスコンテナにしたり、 入れ子にして複雑なレイアウトを実装することができます。
サポートするブラウザを確認することが必要ですが、grid-gap: は便利なので、二次元のレイアウトでなくてもグリッドは使えそうですね。

参考

MDN "grid"
CSS-TRICKS "grid"
Udemy "CSS - The Complete Guide 2020 (incl. Flexbox, Grid & Sass)"
Udemy "Advanced CSS and Sass: Flexbox, Grid, Animations and More!"