3つだけ覚える「flexbox」の使い方


![Kobito.GfdGCw.png](https://qiita-image-store.s3.amazonaws.com/0/32596/8cfd9177-21f0-3f7a-0e2b-293326327f64.png "Kobito.GfdGCw.png")

# 3行で説明、flexboxとは

CSS3から導入されたfloatに変わる新しいレイアウト方法です。

伸びたり並んだりします。

![flexbox-01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32596/beab2964-cb20-4b05-1e2a-d38f1720178e.gif)


# 俺、flexboxのプロパティ何回ググるんだろう問題

flexboxのプロパティめっちゃ多いですね。正直覚えきれませんし、覚えるつもりもなくなってきます。それに、別に複雑なことをやりたいわけではないですね。

具体的には、下記のようなことができれば十分なんです。

 * リキッド2カラムレイアウト
 * スティッキーフッタ（最下部に吸い付くフッタ）

この程度のものであれば、覚えるべきflexbox関連のCSSプロパティの数も絞れそうです。

# 覚えておくべき３つのプロパティ

* display: flex
* flex: 1
* flex-direction: column

これだけでわりとこなせます。以下で、実例をもとに説明します。


# 2カラムレイアウト

![Kobito.82rqsP.png](https://qiita-image-store.s3.amazonaws.com/0/32596/fda41f08-5d7b-f475-1f74-2b6103f30622.png "Kobito.82rqsP.png")

さて、よくある2カラムレイアウトです。
ではまず、`幅を伸ばす要素`と`伸ばさない要素`の二つに分けて考えましょう。

 * `伸ばさない要素`の方には普通に`width: 300px`のように幅を指定します。
 * `幅を伸ばす要素`の方には`flex: 1`を指定します。
 * 上記二要素の親には`display: flex`を指定します。

![add.png](https://qiita-image-store.s3.amazonaws.com/0/32596/4f823bee-0e91-e2ac-7435-7613bdf072ba.png)


`flex: 1`のように指定すると、余白を指定の割合で埋めようとします。例の場合は、flex指定した要素は一つだけですから、余白を100%埋めるように幅が伸びます。

[DEMO](http://hashrock.github.io/flexbox-example/page1.html)
[Source Code](https://github.com/hashrock/flexbox-example/blob/master/page1.html)


```html
<div class="container">
    <div class="left">
      <!-- 左カラム -->
    </div>
    <div class="contents">
      <!-- 右カラム -->
    </div>
</div>
```


```css
.container{
    display: flex;
}
.left{
    width: 300px;
}
.contents{
    flex: 1;
}
```

floatで実現するとなると、このコード量では済まないですね。

# 3カラムレイアウト

![Kobito.3br9Go.png](https://qiita-image-store.s3.amazonaws.com/0/32596/59037052-1a6e-a299-f57d-632fb365b13a.png "Kobito.3br9Go.png")


これも2カラムとそんなに変わりません。固定する部分が二つに増えただけです。

やることは全く一緒です。繰り返しますが、

 * 固定の部分は幅指定
 * 伸ばす部分は`flex: 1`
 * 親要素には `display: flex`

ですね。

[DEMO](http://hashrock.github.io/flexbox-example/page2.html)
[Source Code](https://github.com/hashrock/flexbox-example/blob/master/page2.html)


```html
<div class="container">
    <div class="left">
      <!-- 左カラム -->
    </div>
    <div class="contents">
      <!-- コンテンツ -->
    </div>
    <div class="right">
      <!-- 右カラム -->
    </div>
</div>
```


```css
.container{
    display: flex;
}
.left{
    width: 300px;
}
.contents{
    flex: 1;
}
.right{
    width: 300px;
}

```




# ヘッダ・フッタ（スティッキーフッタ）

![Kobito.Ot1hp4.png](https://qiita-image-store.s3.amazonaws.com/0/32596/32e1ea02-30c8-4d5d-34c0-491130aac8e6.png "Kobito.Ot1hp4.png")

スティッキーフッタとは、平たく言うと、必ずページの末尾にひっついてくるフッタですね。


これ、結局、さっきの「３カラムレイアウト」を、９０度回転させただけです。flexboxの要素の並べ方向を指定するプロパティが、`flex-direction`です。

ここでは縦に並べたいので、親に`flex-direction : column`を指定します。

さらにもう一点。親要素は常に縦幅が画面サイズ以上になるようにします。`min-height: 100vh`を指定します。

[DEMO](http://hashrock.github.io/flexbox-example/page3.html)
[Source Code](https://github.com/hashrock/flexbox-example/blob/master/page3.html)


```html
<div class="container">
    <div class="header">
    </div>
    <div class="contents">
        <!-- コンテンツ -->
    </div>
    <div class="footer">
    </div>
</div>
```

```css
.container{
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}
.header{
    height: 100px;
}
.contents{
    flex: 1;
}
.footer{
    height: 100px;
}
```





# 合わせ技

![Kobito.FpePjX.png](https://qiita-image-store.s3.amazonaws.com/0/32596/be4e1889-4ee0-8652-c18d-92410e654d49.png "Kobito.FpePjX.png")


別名Holy-Grail layoutって呼ばれている気がします。

これも、結局「３カラムレイアウト」と「ヘッダ・フッタ」の組み合わせにすぎません。コードは省略します。

[DEMO](http://hashrock.github.io/flexbox-example/page4.html)
[Source Code](https://github.com/hashrock/flexbox-example/blob/master/page4.html)


# おわりです

![Kobito.ZnF4F6.png](https://qiita-image-store.s3.amazonaws.com/0/32596/ee6041ae-e5bf-05b3-053c-74a79d1a2f2b.png "Kobito.ZnF4F6.png")

簡単でしたね。


# サンプルのソースコード

[Github](https://github.com/hashrock/flexbox-example/)に置いておきました。

https://github.com/hashrock/flexbox-example/

# 他のflexboxプロパティについて

flexboxのプロパティはたくさんありますが、最近Chrome DevToolsに支援機能が追加され、覚えなくて済むようになっています。

下記に練習用のページを用意しました。

[DEMO](https://hashrock.github.io/flexbox-example/devtool-study.html)

ページを開いたら、右クリック→「検証」でDevToolsを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32596/33230949-f7c4-2124-95c5-b33eb44c3e04.png)

このように`display: flex` が設定された要素にはflexボタンが表示されます。マウスオーバーするか、flexボタンを押下すると各プロパティがどういう効き方をしているのか表示することができます。

![flexbox-02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32596/dedf592a-b1b2-3ab9-6438-8c87214e9b93.gif)


containerクラスのついたdivをクリックし、Stylesタブを確認すると、`display: flex` の横にボタンが表示されていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32596/226a2103-60f4-ad26-60cd-f32b4fd461c8.png)

ここでflexboxの各プロパティを変更して、実際どのようにレイアウトが変わるか試すことができます。
実際にやってみましょう。

![flexbox-03.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32596/3c0c636a-2a00-827b-3e58-cd37bf28714a.gif)

`flex-wrap`はflexアイテムを並べて折り返すかどうか、`align-content` や `justify-content`は空いたスペースをどう分配するかに効いてきます。

このツールのおかげで目で見てすぐに効果が確認できるようになり、細かなプロパティを覚えなくても済むようになりました。
ありがたい機能ですね！

# 関連資料

 * [Solved by flexbox](http://philipwalton.github.io/solved-by-flexbox/)
 * [Solved by flexbox和訳版](https://hashrock.github.io/solved-by-flexbox-ja/)

# グリッドレイアウトについて

レイアウトが複雑になってくると、flexboxを複数入れ子にする必要が出ることがあります。
そのようなケースでは[Grid Layout](https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Grid_Layout)の利用を推奨します。

Flexbox / Grid Layout / floatの使い分けに関しては、[icsの記事](https://ics.media/entry/15921)が参考になります。
個人的には、同種の要素を並べる時にflexbox, 異なる要素をレイアウトする時にgridを利用すると、文書構造として良いと思っています。