【🐣成長記録2】Grid Layoutが便利だったので備忘録としてまとめました

# はじめに
こんにちは！ささかまです！
みなさまは横並びレイアウトはどのように実装していますでしょうか？
私はFlexboxを多用していたのですが、最近Grid Layoutに触れる機会があり、試したところすごく便利だったので、今後自分でも見直せるよう備忘録としてまとめてみました！

## Grid Layoutについて
まずはGridについて説明していきます。
私は英語があまり得意ではなく、そもそもGridてなに？状態だったので調べてみました。

> グリッド（grid）とは、格子（状のもの）、方眼（状のもの）、送電網、配管網などの意味を持つ英単語。直線が縦横に規則正しく並んだ図形やそのような構造のもの、また、多数の対象を網目状に繋ぎあわせたものを意味することが多い。
[IT用語辞典 e-words](https://e-words.jp/w/%E3%82%B0%E3%83%AA%E3%83%83%E3%83%89.html)

Gridは日本語で格子状、方眼状といった縦横の直線で規則正しく区切られているもののことみたいです。
MDNでGridについて調べるとこう書かれていました。
>列と行を定義する水平線と垂直線の集合が交差したものです。要素をグリッド上の行と列の中に配置することができます。
[MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout#%E3%82%B0%E3%83%AA%E3%83%83%E3%83%89%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%8B%EF%BC%9F)

Grid Layoutを使うことで、下画像のように大きさの違う要素を格子状に並べて表示することができるようになります。

![スクリーンショット 2024-04-15 14.22.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/3dda6001-1c76-2014-4f4b-82ddda751383.png)

Grid Layoutで出てくる用語や基本の考え方はこちらの記事がわかりやすかったので、引用させていただきます。

>左の図を見てください。表を描くように、線を引いて、格子状にマス目を作ります。それぞれの線には番号が振られます。列（横方向）は左から右へ、行は（縦方向）は上から下へ。この線を<b>ライン</b>、マス目を<b>セル</b>、列や行を<b>トラック</b>と呼びます。
右の図を見てください。このセルに合わせる形で、<b>アイテム（それぞれの子要素）</b>の領域を決めていきます。全てのアイテムを、<b>コンテナ（親要素）</b>で包みます。
![スクリーンショット 2024-04-18 16.54.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/ecbbc684-5bc4-1b4f-a817-93dac3e94d56.png)
[【CSS】Grid Layout を使いこなす – その１ 基本](https://web.hazu.jp/grid-layout-01/)

ではGridを使用する上でよく使うプロパティをまとめていきたいと思います。

## grid-template-columns
`grid-template-columns`はコンテナ内の列のサイズや配置を指定するために使用されます。
下記の例だと左の列から`150px（アイテム1、4）`、`250px（アイテム2、5）`、`1fr（アイテム3、6）`の幅で表示します。
```CSS
grid-template-columns: 150px 250px 1fr;
```
![スクリーンショット 2024-04-22 13.43.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/1ae4d8b1-97c3-5764-49f1-be6839316eeb.png)

## grid-template-rows
`grid-template-rows`はコンテナ内の行のサイズや配置を指定するために使用されます。
下記の例だと上の行から`100px（アイテム1）`、`150px（アイテム2）`、`1fr（アイテム3）`の幅で表示します。
```CSS
grid-template-rows: 100px 150px 1fr;
```
![スクリーンショット 2024-04-22 14.36.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/11b4782b-8053-faa4-6c5d-38eb4cd6db5e.png)

### frって何？(おまけ)
これまで何度か単位として`fr`が出てきましたが、Grid以外に使うタイミングがなく、とりあえず1frにしとけば大丈夫みたいな感じで使ってたので詳しく調べてみました。

まず`fr`の意味ですが、分数を意味する`fraction`の略みたいです。
frを使用することで親要素から見た子要素の大きさを割合で指定することができます。
そのため、先ほど説明した`grid-template-columns`で`1fr 1fr 1fr`を指定すると`1:1:1`の割合でアイテムを表示することができます。
![スクリーンショット 2024-04-22 15.43.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/65795fc0-1a7d-aea1-0c71-c9f4e7230b63.png)


## grid-column、grid-row
先ほど説明した`grid-template-columns`、`grid-template-rows`は親要素のコンテナで各アイテムの高さや幅を指定していましたが、`grid-column`、`grid-row`は子要素である各アイテムの開始と終了の位置を指定します。ラインの数字や`span`などを使うことで指定することができます。

最初の方に説明したこのラインの数字を使って指定します。
<img width="400" alt="スクリーンショット 2024-04-22 15.08.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/c87dced3-9ef4-4177-743c-ec54e90f191e.png">
例えば1行目全体を覆うようなアイテムを表示させたいときはこのように指定します。
```CSS
grid-column: 1 / 3;
```
左にはアイテムの開始ライン、左には終了ラインを指定します。
今回の場合だと開始ライン（列）１から終了ライン（列）３までになっているので1行目全体を覆うアイテムを表示させることができます。
また、`span`を使うことで終了ラインではなく、始まりのラインから何個分のアイテムまでを範囲に含めるかの指定ができます。
```CSS
grid-column: 1 / span 2;
```
上記だと２つ目のアイテムまでなので表示としてはその前の`grid-column: 1 / 3;`と同じになります。

## grid-gap
行と列の余白を指定することができます。
```CSS
grid-gap: 10px;
```
* grid-gap無し
![スクリーンショット 2024-04-22 15.31.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/5efba7eb-1311-ff80-948e-43601ace295e.png)
* grid-gap有り
![スクリーンショット 2024-04-22 15.32.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/47066ec2-50bf-8e0c-8f63-d7dfef448f7c.png)

行と列の間隔を別で指定したい場合は`column-gap:`で列の余白、`row-gap:`で行の余白を指定することができます。
また、`grid-gap:`に値を二つ指定することで、一つ目が行、二つ目が列の余白になります。
```CSS
column-gap: 10px;
```
![スクリーンショット 2024-04-22 15.34.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/b0340e51-84d6-87c6-68c1-b1e13494461c.png)

## repeat()関数
同じサイズのアイテムを繰り返したいときは`repeat()`関数を使用することで、簡単に表示することができます。
`grid-template-columns,grid-template-rows`に指定することができ、最初の引数に繰り返す回数、二つ目の引数にアイテムの幅を順にカンマ(,)で区切って指定していきます。
```CSS
grid-template-columns: repeat(2, 100px);
```
![スクリーンショット 2024-04-22 15.47.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/e36ccc79-fae8-8923-6104-96c552fb621d.png)

また、二つ目の引数のアイテム幅は複数指定することができます。下の例だと100pxと50px幅のアイテムを2回繰り返すことができます。
```CSS
grid-template-columns: repeat(2, 200px 150px);
```
![スクリーンショット 2024-04-22 15.49.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/edb1d29f-656e-02ba-4e35-9fa2415d0ae9.png)

## minmax()関数
minmax()関数を使うことでアイテムの幅の最小値と最大値を決めることができます。
要素が指定された最小サイズと最大サイズの範囲内で自動的にサイズが変動します。
```CSS
display: grid;
grid-template-columns: minmax(100px, 1fr) minmax(200px, 2fr);
```
この例では、`grid-template-columns`に`minmax()`を使用して、アイテムの幅を指定しています。左の列は最小幅が100pxで、最大幅は使用可能なスペースの1割りの割合を持ち、右の列は最小幅が200pxで、最大幅は使用可能なスペースの2割りの割合を持ちます。
`minmax()`を使用することで、アイテムのサイズを柔軟に制御し、レイアウトを調整することができます。

## auto-fill
`auto-fill`はrepeatやminmax()と一緒に使用することが多い気がします。
auto-fillを使うことで、画面幅を広げた時に指定したアイテムの幅と同じスペースができると、そこに新しく空のアイテムを配置します。fillは日本語で「満たす」「充填する」なのでスペースができるとどんどん空のアイテムを追加していきます。
しかし、空のアイテムが原因で`justify-content: center;`を使っても中央揃えにならないみたいなので、そこだけ注意しないといけないです。
![スクリーンショット 2024-04-22 16.10.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/8007a546-94fb-62f9-a1fc-a5cdcd0af33a.png)

## auto-fit
`auto-fit`は先ほどのauto-fillとほとんど同じです。
違うのは画面を広げてスペースができた時の挙動で、こちらは空のアイテムを追加していくのではなく、画面幅に合わせてアイテムが引き延ばされます。
![スクリーンショット 2024-04-22 16.11.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/2e4218c1-b4bf-2d35-7f7a-74ce92f08eb6.png)

## subgrid
Gridを使ってカードを作ると、コンテンツ内の要素の高さが揃わずガタガタでとても見栄えが悪くなってしまいます。そんな問題を解決してくれるのが`subgrid`です。
親要素のCSS Gridを継承できるという機能を持っており、`subgrid`を使用することでJSを使わずにコンテンツ内の要素の高さを合わせることができます。

subgridを使っていないカードはこのように中のテキストなどの影響で高さが揃っておらず、ガタガタであまり見た目が良くありません。
![スクリーンショット 2024-04-22 17.01.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/06d00818-69f6-5205-28a9-5855917710a0.png)

ここにsubgridを指定するとこのようになります。
![スクリーンショット 2024-04-22 18.24.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3313803/88a17fce-f398-80cb-1d60-e6c110029d72.png)
タイトル下のテキストの開始位置が全てのカードで揃っていてsubgridを使っていないものよりも綺麗に表示させることができます。
実装方法はカードにもgridを指定し、subgridを与えるだけです。
```CSS
display: grid;
grid-template-rows: subgrid;
```

# まとめ
今回はGrid Layoutについてまとめました。
まだ完璧に使いこなせていない感じはしますが、今回使い方を調べてまとめたことで、以前よりは理解が深まり上手く使えるようになったのでよかったです。今まで横並びレイアウトはFlexboxを多用していましたが、慣れてしまえばGrid Layoutの方が自由度が高く、使いやすかったので今後はGrid Layoutをうまく活用していきたいと思います。

## 参考サイト
最後に参考にさせていただいたサイトを載せておきます。最後まで見ていただきありがとうございました！
* [【CSS】Grid Layout を使いこなす](https://web.hazu.jp/grid-layout-01/)
* [横幅が広がったときの挙動が変わる！CSS Gridの「auto-fill」と「auto-fit」の違い](https://webrandum.net/css-grid-auto-fill-auto-fit/)
* [入れ子レイアウトがもっと便利に！CSS Subgridの使い方](https://webdesignshake.com/1615/)
* [【CSS】repeat関数の使い方、トラックの幅の指定を繰り返す!](https://shu-naka-blog.com/css/repeat/)
* [CSSのSubgridが全ブラウザ対応。Gridの入れ子の基本から応用までを完全理解する](https://zenn.dev/tonkotsuboy_com/articles/css-subgrid-all-browsers)
* [これは便利！CSS Gridのauto-fillとauto-fitの使い分けでRWDが捗る](https://ascii.jp/elem/000/001/659/1659899/)