Flexboxの基本

# 概要

React Nativeでの開発は楽しいですね。
Reactの「Learn Once, Write Anywhere」がフルに発揮されていると思います。
今回は、React Nativeではなく、React Nativeで柔軟にレイアウトを作成する際に必要となる、
Flexboxについてまとめました。
(CSSベースでまとめています。)

# Flexbox

## Flexboxの用語

### flex container

レイアウトしていきたい要素を含めるための領域。

flex containerが生成されたら、flex-directionが定義される。
flex-directionのdefaultはrow(column縦方向)。

flex-directionに平行のaxisをmain axis、交差するaxisをcross axisと呼ぶ。

#### flex-direction

axisの設定を行う。

- row
- column
- row-reverse
- column-reverse

#### flex-wrap

デフォルトではラップされない。

- nowrap
- wrap
- wrap-reverse

#### flex-flow

flex-directionとflex-wrapを順不同に設定できる。

```css
.container {
	flex-flow: column wrap
}
```


#### justify-content

main axisに余白がある時、余白の埋め方指定できる。

- flex-start
- flex-end
- center
- space-between
- space-around

#### align-items

cross axisに余白がある際に、余白の埋め方を指定できる。

- flex-start
- flex-end
- center
- stretch
	- 余白を埋めてくれる。
	- 高さを指定していたら反映されない。

#### align-content

wrapされた行をまとめて操作する。

- flex-start
- flex-end
- center
- space-between
- space-around

### flex item

レイアウトしていきたい要素。

flex-directionに沿って要素が作られる。

#### order

個別に要素の並び替えの順番を指定する事ができる。
デフォルトでは全ての要素が0になっている。
orderが同じ場合は、htmlの書かれた順番に並び替えられる。

#### align-self

特定の要素だけを、cross axis方向に設定できる。

- flex-start
- flex-end
- center

#### flex-grow

余白がある時に、それぞれの要素の幅がどの様になるかを決める。
(余った余白をどの要素に付けるかを指定できる。)

#### flex-shrink

要素がflex-containerから溢れた時にどうするかを決める。


#### flex-basis

要素の基本となる幅を設定する。

## flexBoxの作り方

親要素に```display:flex;```を設定する。

- 子要素のみがflexStyleになり、孫要素はflexにはならない。

## flex-itemsでのflex

flex-start, flex-shrink, flex-basisに対応する。

```css
.foo {
	flex: 0 1 auto;
}
```

- 長さっぽい値がきたらflex-basisになる。
- 数字が1個ならflex-startになる。

## flex-growの仕組み


```css
.container {
  width: 300px;
  height: 300px;
  color: #FFFFFF;
  background-color: #EEEEEE;
  display: flex;
}

.box {
  width: 80px;
  height: 80px;
}
.box-1 {
  background-color: tomato;
  flex: 1 1 80px;
}
.box-2 {
  background-color: slategray;
  flex: 2 1 80px;
}
.box-3 {
  background-color: pink;
  flex: 3 1 80px;
}
```

- ①まずは余っている余白の幅を求める。
	- 今回であれば60px
		- 300 - 80 * 3
- ②余っている余白の比率を記載する。
	- 今回であれば1:2:3

比率は以下の計算しきになる。

余りの余白(60px) / 比率の合計(6) = 10px(1flex grow)

## flex-growの仕組み


```css
.container {
  width: 300px;
  height: 300px;
  color: #FFFFFF;
  background-color: #EEEEEE;
  display: flex;
}

.box {
  width: 80px;
  height: 80px;
}

.box-1 {
  background-color: tomato;
  flex: 0 1 120px;
}
.box-2 {
  background-color: slategray;
  flex: 0 2 120px;
}
.box-3 {
  background-color: pink;
  flex: 0 3 120px;
}
```

- ①まずははみだしている余白の幅を求める。
	- 今回であれば60px
		-  120 * 3 -300
- ②はみ出した部分に併せてどれだけ縮めるかの比率を記載する。
	- 今回であれば1:2:3

比率は以下の計算しきになる。

(1*120) / それぞれの割合で広がった場合(1*120 + 2*120 + 3*120) * 余っている幅(60) = 10

- 1は10px引く(110px)
- 2は20px引く(100px)
- 3は30px引く(90px)

## flexboxとmargin:autoの組み合わせ

各flex-itemに対して、margin-XXX: autoを指定すると上手い具合で左寄せ、右寄せが可能である。

## 要素を上下左右中央に配置する

- justify-content: center;
- align-items: center;

これだけで上下左右中央揃えが可能である。

## 3カラムの作り方

![スクリーンショット 2016-11-11 16.49.48.png](https://qiita-image-store.s3.amazonaws.com/0/129216/913c5756-5398-acda-f93b-8abedcf9537b.png "スクリーンショット 2016-11-11 16.49.48.png")


```html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>FlexBoxの練習</title>
        <link rel="stylesheet" href="./styles.css" media="screen" title="no title">
    </head>
    <body>
        <header class="header">
            header
        </header>
        <div class="container">
            <div class="left-content">
                left
            </div>
            <div class="center-content">
                center
            </div>
            <div class="right-content">
                right
            </div>
        </div>
        <footer class="footer">
            footer
        </footer>
    </body>
</html>
```

```css
.header {
  background-color: #DDD;
}
.left-content {
  background-color: tomato;
  flex: 0 100px;
}
.center-content {
  background-color: skyblue;
  flex: 1 100px;
}
.right-content {
  background-color: pink;
  flex: 0 100px;
}
.footer {
  background-color: #DDD;
}

.container {
  display: flex;
}
```

## レスポンシブデザインの作り方

```css
.header {
  background-color: #DDD;
}
.left-content {
  background-color: tomato;
  flex: 0 100px;
}
.center-content {
  background-color: skyblue;
  flex: 1 100px;
}
.right-content {
  background-color: pink;
  flex: 0 100px;
}
.footer {
  background-color: #DDD;
}

.container {
  display: flex;
}

@media all and (max-width: 500px) {
  .container {
    flex-direction: column;
  }
  .center-content {
    order: 0;
    flex: 100%;
  }
  .left-content {
    order: 1;
    flex: 100%;
  }
  .right-content {
    order: 2;
    flex: 100%;
  }
}
```

# 終わり

今まではBootstrapやMaterialize.cssのフレームワークに頼るCSS生活でしたが、
Flexboxを導入すれば、かなり柔軟にレイアウトが作成できると思います。

React Nativeでも必要な知識になると思うので、
どんどん使っていきたいと思います。