4.4 FlexBox

# FlexBox
「Flexible Box Layout Module」の略でレイアウトの作成でよく使用されます。
例えば、要素を横並びに配置したいときや、要素を上下中央に配置したい時など。

↓とてもわかりやすいサイトがありましたのでこちらで説明していきます。
https://webdesign-trends.net/entry/8148#CSS_Flexbox


# よく使用する属性
基本以下５つの属性を覚えておけばほとんど実現できるようです。

1. 左右をピッタリで等間隔`justify-content: space-between;`
2. 横並びから縦並びに変更`flex-direction: column;`
3. 折返し`flex-wrap: wrap;`
4. 順番を入れ替える`flex-direction: row-reverse;`
5. 上下を中央にそろえる`align-items: center;`




<details><summary>今回はこちらのボックスを使用して説明していきます。</summary>
CSSの復習も兼ねて実際にコピペして画面表示させてみましょう。
<div>
index.html

```html
<div class="item">
  <div class="item-img">
    <img
      src="https://haniwaman.com/cms/wp-content/uploads/2018/10/dummy.jpg"
      alt=""
    />
  </div>
  <div class="item-body">
    <div class="item-title">見出し見出し見出し見出し</div>
    <p>
      テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
    </p>
  </div>
</div>
```

style.css

```css
.item {
  width: 100%;
}
img {
  width: 100%;
}
.item-body {
  padding: 0;
}
.item-title {
  margin: 0 0 8px;
  font-size: 20px;
  font-weight: 700;
  color: #ef5350;
}
.item-body p {
  font-size: 16px;
  font-weight: 400;
  color: #333;
}
```
</div>
</details>

---

1. 左右をピッタリで等間隔`justify-content: space-between;`

    ①ボックスを３つ並べて、`<div　class="items"></div>`で囲みます。
    　※使用するボックスの２つ目、３つ目は以下にすると見やすくなります。
    　２つ目https://haniwaman.com/cms/wp-content/uploads/2018/10/dummy2.jpg
    　３つ目https://haniwaman.com/cms/wp-content/uploads/2018/10/dummy3.jpg
    ②スタイルを追加します
  
    ```css
.items {
  display: flex;
  justify-content: space-between;
}
.items .item {
  width: 30%;
}
```

2. 横並びから縦並びに変更`flex-direction: column;`
    row（横並び）が一般的だと思いますが、columnで縦並びにもできます。
    レスポンシブ時によく使用しますので、画面幅が`767px`まではスマホ画面でのレイアウトでよくある縦並びになるようにします。

    以下スタイルを追加。

    ```css
@@media screen and (max-width: 767px) {
	.items {
		flex-direction: column;
	}
	.items .item {
		width: 100%;
	}
}
```

3. 折返し`flex-wrap: wrap;` 
    <details><summary>index.htmlにこちらを追加してください。</summary>
<div>

    ```html
      <div class="item">
        <div class="item-img">
          <img
            src="https://haniwaman.com/cms/wp-content/uploads/2018/10/dummy4.jpg"
            alt=""
          />
        </div>
        <div class="item-body">
          <div class="item-title">見出し見出し見出し見出し</div>
          <p>
            テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
          </p>
        </div>
      </div>
      <!-- /.item -->
      <div class="item">
        <div class="item-img">
          <img
            src="https://haniwaman.com/cms/wp-content/uploads/2018/10/dummy5.jpg"
            alt=""
          />
        </div>
        <div class="item-body">
          <div class="item-title">見出し見出し見出し見出し</div>
          <p>
            テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
          </p>
        </div>
      </div>
      <!-- /.item -->
      <div class="item">
        <div class="item-img">
          <img
            src="https://haniwaman.com/cms/wp-content/uploads/2018/10/dummy6.jpg"
            alt=""
          />
        </div>
        <div class="item-body">
          <div class="item-title">見出し見出し見出し見出し</div>
          <p>
            テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト
          </p>
        </div>
      </div>
      <!-- /.item -->
```
</div>
</details>

    そのままだと画面幅いっぱいに要素が表示されているかと思います。
    これは`class="item"`に対して`width: 30%`と指定しているにも関わらず、Flexboxが横幅いい感じに調整して横並びにしていることが原因です。
    この問題を解消するために、（画面幅を越えるように横幅を指定した場合）折り返されるようにしなければいけません。
    <b>そこで`class="items"`に`flex-wrap: wrap;`を追加。</b>
    以下のスタイルになります。

    ```css
.items {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
}
```

4. 順番を入れ替える`flex-direction: row-reverse;`

    2.で並びの向きを指定する属性`flex-direction`がありましたが、これを使用して**逆向き**にもできます。
    全ての要素を逆向きにしても面白くないので、奇数だけ逆向きにしていきます。
    ①画像の横に見出しとテキストを配置します。`.items .item`のスタイルを以下に変更。

    ```css
.items .item {
  /* width: 30%; */
  display: flex;
  margin: 0 0 24px;
}
```
    ②画像にスタイルを微調整します。
    　※こちらはあっても無くても良い（今回の要素の順番を変更することに直接関係しないため）

    ```css
.items .item-img {
  width: 50%;
  padding: 0 12px;
}
```
    ③奇数の場合に並びを逆にするスタイルを追加。
    　セレクタの語尾に`:nth-child(odd)`を追加することで実現できます。
    　また、偶数の場合は`:nth-child(even)`でできます。
    　その他は要素の順番の指定方法の詳細↓
    　http://ideahacker.net/2013/06/28/5571/

    ```css
.items4 .item:nth-child(odd) {
  flex-direction: row-reverse;
}
```

5. 上下を中央にそろえる`align-items: center;`

    ヘッダーで使用する場面がよくあるので、先ほどの記事風の画面にヘッダーを追加して説明します。
    <details><summary>こちらを追加</summary>
<div>

index.htmlの`<body>`に追加（ヘッダなのでbodyの次の行がいいかと）

```html
    <header>
      <div class="items5">
        <div class="item-logo"><a href="">ロゴ</a></div>
        <nav class="item-nav">
          <ul>
            <li><a href="">Top</a></li>
            <li><a href="">About</a></li>
            <li><a class="active" href="">Blog</a></li>
            <li><a href="">Profile</a></li>
            <li><a href="">Contact</a></li>
          </ul>
        </nav>
        <!-- /.item-nav -->
      </div>
    </header>
```

以下CSSに追加。

```css
.items5 {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 100px;
  box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.16);
  padding: 0 24px;
}
.item-logo > a {
  text-decoration: none;
  color: #333;
}
.item-nav li {
  display: inline-block;
  padding: 0 12px;
}
.item-nav a {
  text-decoration: none;
  color: #333333;
}
.item-nav a.active, .item-nav a:hover {
  border-bottom: 3px solid #ef5350;
}
```
</div>
</details>


# 参考
https://webdesign-trends.net/entry/8148#CSS_Flexbox

https://haniwaman.com/flexbox/

http://ideahacker.net/2013/06/28/5571/