Grid Layout タイルレイアウトの実装

# はじめに

この記事は「[【マイスター・ギルド】本物のAdvent Calendar 2022](https://adventar.org/calendars/7794)」12日目の記事です。



こんにちは。
業務ではマークアップをしているkiitaです。

今回はGridレイアウトについて書こうと思います。

このテーマを選んだ経緯は、普段Flexばかり使っててGridあんまり分かってなかったからです。
よくあるレイアウトは大体Flexで実装できるので、とりあえずFlex使いがちになってました。

が、Grid Layoutに対応してるブラウザも揃ってきて、Gridの記事もよく見かけるので、そろそろGridと向き合うか～と今に至るわけです。（遅い）


なので、この記事は
- 普段はFlex使い
- Gridってよく聞くけど、まぁFlexでいけるしな～
- といいつつ、Grid気になる

という人に向けた記事となってます。


# FlexとGrid
FlexとGridの違いは大体こんなイメージで、それぞれ向いてるレイアウトがあるので、場合によって使い分ける形になるかと思います。

Flex
軸に沿ってアイテムを並べていく横並びに強いcss

Grid
行・列に沿ってアイテムを並べていく複数行のレイアウトに強いcss

イメージ↓
![grid1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075212/de96c2bf-5278-2737-a5dd-66ced4d3bbce.png)


構造とか使い方については、めちゃくちゃわかりやすく書いてくださってる記事があったのでこれだけ読んでおけば大丈夫と思います！
https://qiita.com/kura07/items/e633b35e33e43240d363


# 実際に使ってみる

## タイルレイアウトをGrid Layoutでかく
以前[Flexを使ったタイルレイアウト（カードが並んでるようなレイアウト）の記事](https://qiita.com/kiita_chi/items/b7b278fff276c4bb6eab)を書いたんですが、タイルレイアウトはGridの方が向いているとのことなのでGridで書き直してみたいと思います。


### Gridの設定
Gridを使用するときはコンテナ（Gridをあてたい大枠部分）に以下の順番で指定します。

1. コンテナに`display: grid`を指定
1. コンテナに`grid-template-columns`、`grid-template-rows`を指定（横幅・縦幅を指定）
1. レイアウトに合わせて、適したプロパティを自由に指定



今回使っているプロパティは以下になります。
#### `repeat（繰り返し数、サイズ）`
要素を繰り返し並べたいときに使えるrepeat関数
例：`grid-template-columns: repeat(3, 100px);` を指定すると、100pxのボックスが3つ並ぶ


今回は`grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));`としています。
auto-fillとminmaxについては以下で説明します。

#### `auto-fill/auto-fit`
この2つの違いは、余った余白をどうするかという点になります。

auto-fill：スペースがある場合、空のスペースができて要素ごとの幅は維持
auto-fit：スペースがある場合、スペースを埋めるように要素が広がる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075212/6ed1ea58-cee0-cdd1-bc7d-7deb83b3ba6d.png)

auto-fill, auto-fitを使用すればメディアクエリを指定しなくてもいい感じにレイアウトを保ってくれるので今回使用しました。
（ニュース記事のレイアウトという設定なので、記事数が1つのときでも要素の幅は保つようにauto-fillを使ってます）

※PCでは4列、TABでは3列で表示など細かい指定がある場合は、メディアクエリでの指定が必要になってきます

#### `minmax(最小値、最大値)`
幅の最小値、最大値を指定できます。

`fr` ：fraction(分割)の略。余白があるときに比率で幅を指定できます。
今回の場合、`minmax(200px, 1fr)`で通常は1frの幅で表示されていて、最小値は200pxなので200pxより小さくならないようになってます。

以上でスタイルをあてるとこのような記述になります。

```scss
 .news-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 32px 25px;
  }
```

めっちゃ短い！！

### Flexの場合
gapを使ってるので、marginなどで余白をとるよりかは少ない記述にはなっていますが、レスポンシブ対応など細かく設定していくとやっぱり記述が多くなっていく、、

```scss
  .news-list {
    display: flex;
    flex-wrap: wrap;
    gap: 45px 5%;
    @media screen and (max-width: 767px) {
      flex-direction: column;
    }
  }
  .article {
    width: 30%;
    @media screen and (max-width: 767px) {
      width: 100%;
    }
  }
```

Gridは、親要素（今回だとnews-list）にコンテナーとなる指定と、幅の設定なども一緒にできるところが簡潔にまとめられて良いなと今回使ってみて思いました。

以下、全体のコード
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="rNKgRZM" data-user="mgkita" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mgkita/pen/rNKgRZM">
  grid layout</a> by chisato (<a href="https://codepen.io/mgkita">@mgkita</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# おわりに
Grid Layoutについて、掘れば掘るほど色んなプロパティがあって実装の引き出しが増えそうだなーと思いました。

対応ブラウザについて下記サイトで確認しながら、今後も新しい実装方法を試していきたいと思います。

Gridの対応ブラウザ
https://caniuse.com/?search=grid