CSS Grid Layoutを少しさわってみた

## 最初に
社内向けに書いたものを再編集しました。

最近Grid Layoutについての記事をよく目にしますよね。
flexboxも案件に使えるようになりましたが、未だにレガシーブラウザに対応しなきゃならない案件抱えてるとflexboxですらpolyfill使わないとならないとか地獄デスヨネ。
そこで個人的に、レイアウト時にできればfloatでレイアウトしたくない、もしくはもう少し楽になることを探していることもあって、

- floatだと一つ親要素（Wrapper）を作ったりなど、html要素の数が増える傾向になる
- floatを使うとclearfix的なことも考えないとならない
- アイテム間の余白調整がfloatやflexboxより楽になるといいな
- Bootstrapなどで採用されているグリッドシステムが必要なくなるかも？
  - 少なくともrow/col-x/col-md-xのような書き方はなくなるかも？
- デザイン側でチャレンジされる場合も対応できそう
- 細かいレイアウト変更に対応できそう（要素の入れ替え案件に対応できるような）
- というか、たとえ1行でも書かなくていいなら減らしたい（つまりめんどくさい）

という怠惰な希望的観測から、
使うにあたって感じたことや調べてみたことを少しだけまとめました。
基本的な使い方はWebを検索すれば溢れていますので細かいところは今回言及しません。


## レイアウトの方法

まず、下記のようなHTMLとして

```
<div class="container">
  <div class="item1">item 1</div>
  <div class="item2">item 2</div>
  <div class="item3">item 3</div>
  <div class="item4">item 4</div>
  <div class="item5">item 5</div>
  <div class="item6">item 6</div>
</div>
```

CSSは

```
.container {
  display: grid;
}
.item1{}
.item2{}
.
.
.
* itemの色分けは省略
```
![スクリーンショット 2018-03-28 14.10.00.png](https://qiita-image-store.s3.amazonaws.com/0/30278/fb7291a5-93f3-18c8-8431-b04ff42a7beb.png)

`display: grid;` だけでgridになりますが、これだと単純にブロック要素が順に並んでいるだけです。

次に、gridの列（column）と行（row）を指定します。

```
.container {
  display: grid;
  grid-template-columns: 150px 150px 150px;
  grid-template-rows: 50px 50px;
}
```
![スクリーンショット 2018-03-28 14.16.04.png](https://qiita-image-store.s3.amazonaws.com/0/30278/b1e44298-7872-595d-b91a-3daea4742a27.png)

グリッドトラックを作ります。
grid-template-columnsプロパティの数で列が、
同様にgrid-template-rowのプロパティの数で行が決まります。

---
指定できる新しい単位として`fr` があり、`余白がある場合その要素をどれくらい伸縮するか`を設定できます。
例えば、1frを2つのときは、2分割して1：1で配置します。
仮に`grid-template-columns: 150px 2fr 1fr;`とすると、3分割して1つは150px、残りを2：1で割り振って配置します。
![スクリーンショット 2018-03-28 15.23.13.png](https://qiita-image-store.s3.amazonaws.com/0/30278/705cb55d-9889-c982-a86f-0c3395051c2a.png)

また、

```
grid-template-columns: 1fr 1fr 1fr;
```

のような記載の場合、`repeat()` を使うと繰り返すことができます。（IE未対応）

```
grid-template-columns: repeat(3, 1fr);
```

`repeat()` はトラックリストの一部にも使えます。

```
grid-template-columns: 150px repeat(3, 50px);
```
この場合、4分割して、150pxが1つ、50pxが3つ配置されます。

---
先程の3x2の状態から
![スクリーンショット 2018-03-28 14.16.04.png](https://qiita-image-store.s3.amazonaws.com/0/30278/f72a5782-15b7-6ecd-1e24-eddc69ceefcf.png)
各アイテムを変更してみます。

```
.container {
  display: grid;
  grid-template-columns: 150px 150px 150px;
  grid-template-rows: 50px 50px 50px;
}

.item1 {
  grid-column: 1 / 3;
}

.item2 {
  grid-column: 3 / 4;
}

.item3 {
  grid-row: 2 / 4;
}

.item4 {
  grid-column: 2 / 4;
}

*各itemのbackground-colorは省略
```

3x3の配置と、各アイテムの位置を変更してみました。

![スクリーンショット 2018-03-28 18.45.47.png](https://qiita-image-store.s3.amazonaws.com/0/30278/9c1cb960-7466-943b-3b3d-d1bc32c878a4.png)


`grid-column`や`grid-row`プロパティをアイテムに指定しますが、
ここでの考え方は列・行を分割した線であるグリッドラインで考えます。

3x3の場合、グリッドラインは
![gridline.png](https://qiita-image-store.s3.amazonaws.com/0/30278/05ee537d-019b-9601-2f2e-ccea9fe77bc8.png)
このようになります。

- `.item1`は列の1~3まで
- `.item2`は列の3~4まで
- `.item3`は行の2~4まで
- `.item4`は列の2~4まで

ということになります。

簡単にレイアウトしましたが、他に便利な機能やプロパティは沢山あります。
[グリッドレイアウトの基本的な概念 - CSS | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout)


## flexbox、floatとの使い分けは？

Grid → 配置の次元が二次元→ 縦横に配置できる
flexbox → 配置の次元が一次元 →配置が一方向のみ（折り返しはする）

Gridの場合、HTMLを編集せずにレイアウトを再編成できるので、場所の入れ替えが発生したりなど改修が容易になる反面、先々の運用を考えて柔軟に対応できる設計、判断が必要になるかと思います。
極論を言えばGridを使ってHTML側はコンテンツ順番を適当にして書き、CSSでコンテンツの順番を指定するようなことも、やろうと思えばできてしまいます。

が、「HTMLは論理的な順番で記述し、Gridは視覚的な順番の変更にのみ使いましょう」ということが仕様に書かれていたりします。
[CSS Grid Layout Module Level 1 Reordering and Accessibility](https://www.w3.org/TR/css-grid-1/#order-accessibility)

様々な側面から考えると

- Gridでレイアウトするのはページ全体のハコなど、ある程度大きな領域を分割するのに向いている感。
- ナビゲーションや画像一覧、実案件で言えば店舗カセットなど、同じアイテムを繰り返し表示、もしくは均等に整列するような場合はflexboxのほうが便利かも
- 画像アイテムにテキストを回り込ませるようなものにはfloat

になってくるのかなと。

## 実案件への投入は？

一見良さげに見えるGridですが、基本的なレイアウトをするにもまだIE10/11対策などでプレフィックスを使う必要があります。
`minmax()`, `repeat()`など便利な記法もIE10/11やChrome for Android、Android webviewの一部で未対応のようです。

とは言え、対策としてAutoprefixerで対応が可能な部分もあります。
[AutoprefixerがパワーアップしてCSS GridのIE 11対応がバリ楽になってた - Qiita](https://qiita.com/tonkotsuboy_com/items/bce73685cd6b1ea511dc)

特にWindows10 IE11は、サポートが2025年10月15日までとか、あと7年も長い冬は続きます。
[一目で分かる、各Windows OSでのInternet Explorerのサポート終了時期](http://www.atmarkit.co.jp/ait/articles/1503/11/news134.html)

そこでレガシーを除くことができたら...IEを除外できれば...そんなことは気にせず採用なのかもしれませんが、
じゃあどうしたら良いの？ということを考えると、Gridよりもflexboxのほうが現状はベターなのかもしれません。

判断が難しいところではありますが、訪れるユーザーの分布を踏まえた上で、どのブラウザまで拾うかという判断やビジネス的な判断もあるので、使い所は慎重に見極めたいところですね。

おわり。