CSS Grid Layout について

先日の macOS と iOS のアップデートに [CSS Grid Layout Module](https://www.w3.org/TR/css3-grid-layout/) が実装された Safari のバージョンが入り、とうとう全てのモダンブラウザで使用可能となりました。非常に柔軟に、直感的にグリッドを表現することができます。

![image](https://qiita-image-store.s3.amazonaws.com/0/6598/e46714b6-9390-3f85-dc41-e1b3971daabf.png)

[Can I Use](http://caniuse.com/#search=grid)

## Grid の定義

ある要素をグリッドレイアウトしたいとき、その親要素に `display: grid` もしくは `display: inline-grid` を指定します。この親要素のことをグリッドコンテナ、グリッドレイアウトされる子要素のことをグリッドアイテムと言います。

グリッドコンテナには `grid-template-column` と `grid-template-row` というプロパティを指定することができます。それぞれ、列と行のグリッドのサイズをその数だけ指定します。

例: 3行5列のグリッド

```css
.container {
  grid-template-columns: 40px 50px auto 50px 40px;
  grid-template-rows: 25% 100px auto;
}
```

## グリッドコンテナに指定できるプロパティ

`## Grid の定義` で紹介したプロパティ以外のグリッドコンテナに指定できるよく使うプロパティの紹介です。

### grid-gap

正確には `grid-gap` は `grid-column-gap` と `grid-row-gap`  のショートハンドです。グリッドアイテム間の列と行の間の余白を指定します。

例:  列は10px, 行は15pxの余白

```css
.container {
  grid-gap: 10px 15px;
}
```

### justify-items, align-items, justify-content, align-content

これらは Flexbox レイアウトでも使ったプロパティです。仕様的にはこれらは Flexbox のものではなく、 [Box Alignment Module](https://www.w3.org/TR/css-align-3/#justify-items-property) という仕様で、グリッドコンテナに対しても使えます。

グリッドアイテムを整列させるプロパティで、CSS Grid で使われる新しいものではないので使い方は省略します。

### grid-template-areas

グリッドアイテムに対して名前を付けるプロパティです。覚える必要はありません。

```css
.container {
  grid-template-columns: 50px 50px 50px 50px;
  grid-template-rows: auto;
  grid-template-areas: 
    "header header header header"
    "main main . sidebar"
    "footer footer footer footer";
}
```

書き方がめちゃくちゃ気持ち悪いです。`.` は空のグリッドに指定します。

## グリッドアイテムに指定できるプロパティ

グリッドコンテナの子要素、実際にグリッドレイアウトされるグリッドアイテムに対して指定できるプロパティの紹介です。ちなみに、グリッドアイテムには `float`, `clear`, `vertical-align` は適用されません。

### grid-column, grid-row

`grid-template-column` と `grid-template-row`　でグリッドを定義し、どの要素をどこに配置するかを決定するのがこれらのプロパティです。正確には、 `grid-column` は `grid-column-start` と `grid-column-end` のショートハンドで、 `grid-row` は `grid-row-start` と `grid-row-end` のショートハンドです。また、 `grid-area` という、`grid-column` と `grid-row` のショートハンドもありますが、`grid-column` と `grid-row`　だけ使うのがわかりやすいと思います。

これらのプロパティはグリッドラインを指定します（[Line-based Placement](https://www.w3.org/TR/css3-grid-layout/#line-placement) と呼ばれたりもします）。

![Screen Shot 2017-04-13 at 19.27.38.png](https://qiita-image-store.s3.amazonaws.com/0/6598/9402f7eb-fe9d-42eb-61b9-985b5043c289.png)



`grid-column` では列の、`grid-row`では行のスタートラインとエンドラインを指定します。

```css
.container {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-gap: 10px;
}

.item-a {
  grid-column: 2 / 3;
  grid-row: 1 / 2;
}

.item-b {
  grid-column: 1 / 2;
  grid-row: 2 / 3;
}
```

### justify-self, align-self

これも Flexbox レイアウトのときもありました。指定したグリッドアイテムを整列されるプロパティです。

## 参考資料

- [仕様書](https://www.w3.org/TR/css3-grid-layout/)
- [A Complete Guide to Grid](https://css-tricks.com/snippets/css/complete-guide-grid/)
- [CSS Grid Layout Terminology, Explained](https://bitsofco.de/css-grid-terminology/)
- [morishitterの CSS Grid に関するブックマーク一覧](https://pinboard.in/search/u:morishitter?query=grid+css)

## 余談

"グリッド"は、今までも `<table>`タグ, `float`, `display: inline-block`, `display: table`, Flexbox などを使って表現することができました。しかし、CSS Grid というグリッドのための仕様が作られ、プリプロセッサーの mixin や グリッドのためのフレームワークを使わなくても、グリッドを作れるようになりました。僕は、CSS Grid が使える1番の恩恵は、`display: grid` と書くことでグリッドが表現でき、コードにデザインの意図が載ることだと思っています。あと、CSS Grid のプロパティも Flexbox のときのように、グリッドコンテナとグリッドアイテムのどちらのプロパティなのかを意識すると覚えやすいと思います。

ちなみに、`display: subgrid` という、グリッドアイテムをグリッドコンテナにし、その子要素をグリッドレイアウトするための値もありますが、これは Level 2 の仕様に移動し、現在 Firefox 以外では実装されていません。今後は、グリッドを表現するときは CSS Grid、コンポーネント内のレイアウトは Flexbox という使い方が良いと思います。