CSSグリッドレイアウト入門

# CSSグリッドレイアウトとは？

mozillaのサイトによると、

> CSS グリッド レイアウトは、行と列で要素を配置することのできる2次元レイアウトをwebの世界にもたらします。 CSSグリッドは、多くの異なるレイアウトを表現するために利用できます。1つのページを領域毎に分割したり、サイズや位置、レイヤーの関係性を定義することに優れています。

https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Grid_Layout

行と列…。どこかで聞いたことのある単語だ。行と列といえばテーブルが思い浮かぶけれど…

> グリッドレイアウトを使うことで、テーブル組みと同じように、列と行を揃えて要素を記述することができます。 しかしテーブル組みとは異なり、グリッドレイアウトは内容の構造を持っていないが故に、テーブル組みでは不可能であった幅広い種類のレイアウトが可能です。

https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Grid_Layout

なるほど。わかったようなわからないような。
とりあえずCSSグリッドレイアウトを用いてHTMLを作ってみる。

の前に、一応対応ブラウザを調査。(2017/10/31現在)
https://caniuse.com/#feat=css-grid
IE11はベンダープレフィックスが必要だが、他の主要ブラウザはだいたいサポートしている。

# CSSグリッドレイアウトの基本

それではまずどんなレイアウトを実現したいか考える。
今回は以下の画像のようなよくあるシンプルなレイアウトとする。

![gridlayout1.png](https://qiita-image-store.s3.amazonaws.com/0/123511/6576d2c8-09c4-874e-bb6f-6658223ab1c2.png)

HTML的には、

```html
<body>
    <header>ヘッダー</header>
    <nav>ナビ</nav>
    <div id="ads">広告</div>
    <article>記事</article>
    <footer>フッター</footer>
</body>
```

となる。

まずはグリッドレイアウトしたい要素を囲む要素に`display:grid`を指定する。
この場合は、body要素に`display:grid`を指定。これがコンテナとなる。
続いてコンテナの中身のアイテムをどう区分けするかを指定する。
その指定には、

- grid-template-rows
- grid-template-columns

と使う。この2つでどれくらいの間隔でアイテムを配置するか指定する。
grid-template-rowsは、上から順にアイテムの高さを半角スペースで区切って指定。
grid-template-columnsは、左から順にアイテムの幅を半角スペースで区切って指定。

```css
body {
    display: grid;
    grid-template-rows: 80px 100px 100px 50px;
    grid-template-columns: 150px 1fr;
}
```

行は上から順に`80px 100px 100px 50px`の高さで指定。列はいちばん左のアイテムの幅が`150px`で、残りの幅全部が2つ目のアイテムとなる。
このとき`fr`という単位が出てくるが、これは指定された長さから差し引いた残り全部という意味。
これでコンテナ内でアイテムを区切ることとなった仮想線に番号が振られる。縦横それぞれ左上から1,2,3となる。0からでないことに注意。
この数字を用いて、実際に要素をそれぞれの枠に当てはめていくのがグリッドレイアウトの基本となる。
上掲の画像に番号を加えてみると、

![gridlayout2.png](https://qiita-image-store.s3.amazonaws.com/0/123511/f47bc957-2203-6071-4726-e4deeb78962f.png)

ここからそれぞれの要素を配置していく。
配置には

- grid-row
- grid-column

を使う。

```css
header {
    grid-row: 1;
    grid-column: 1 / 3;
}
```

`grid-row: 1;`は`grid-row: 1 / 2;`の省略形。
これは行番号1から2、列番号が1から3の間のアイテムがheaderとなることを指定している。
同様に、

```css
body {
    display: grid;
    grid-template-rows: 80px 100px 100px 50px;
    grid-template-columns: 150px 1fr;
    font-size: 2em;
}
header {
    grid-row: 1;
    grid-column: 1 / 3;
    background: #87cefa;
}
nav {
    grid-row: 2;
    grid-column: 1;
    background: #ffb6c1;
}
#ads {
    grid-row: 3;
    grid-column: 1;
    background: #fff8dc;
}
article {
    grid-row: 2 / 4;
    grid-column: 2;
    background: #f8f8ff;
}
footer {
    grid-row: 4;
    grid-column: 1 / 3;
    background: #7fffd4;
}
```

とすると、以下のようなレイアウトのHTMLが出来上がる。わかりやすい。

![gridlayout3.png](https://qiita-image-store.s3.amazonaws.com/0/123511/f3d946e6-ae3c-84f0-f042-f874cb2223f9.png)

```html
<body>
    <header>ヘッダー</header>
    <nav>ナビ</nav>
    <div id="ads">広告</div>
    <article>記事</article>
    <footer>フッター</footer>
</body>
```

ここにはtableもfloatも、ただ配置を整えるだけのdivもない。
HTMLの要素がその意味するものを忠実に表している。
非常に見通しのよいHTML設計となっていると思う:thumbsup_tone1:

# 最後に
調べると、さらに複雑なグリッドレイアウトを可能とする記述もあるが今回はここまで。
ネストされまくったdivから逃れるためにもCSSグリッドレイアウトはよいかもしれない。

# 参考
[CSS グリッドレイアウト - CSS | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Grid_Layout)
[これからのCSSはmargin禁止！？CSSグリッドレイアウトやコンポーネント指向なCSSについて、矢倉さんに聞いてきた！ | HTML5Experts.jp](https://html5experts.jp/shumpei-shiraishi/24439/)