HTML/CSS初心者は必見！ どんなデザインでも自由自在にできるFlexbox入門

# はじめに
今回は要素を綺麗に配置するときに、大変役立つFlexboxの使い方について紹介します！

ここでは、要素 (アイテム) が入っている箱のことをコンテナと呼んで説明します。

# YouTube動画
動画で学びたい方はこちらもどうぞ！
[【YouTube動画】 HTML/CSSのFlexboxについて詳細解説！ これでどんなデザインでも自由自在！【Flexbox入門】](https://youtu.be/84VY9zho4_g)
[![HTML/CSS の flexbox について詳細解説！ これでどんなデザインでも自由自在！【Flexbox入門】](https://img.youtube.com/vi/84VY9zho4_g/0.jpg)](https://youtu.be/84VY9zho4_g)

# GitHub
コードのサンプルをGitHubにアップロードしてます！
Pathや一部コードを修正する必要がありますが、ローカルで試してみたい方はこちらもどうぞ！
https://github.com/yassun-youtube/html-flexbox-samples

# コンテナ内の全要素の配置
コンテナに入っている要素の並びを一括で指定したい場合は、flex-direction, justify-content, align-items, align-content, flex-wrapなどがあります。

# flex-direction
flex-directionは、コンテナ内の要素を<b>どの軸方向で並べるか</b>を決めるプロパティです。

```html
<div class="container" style="display: flex; flex-direction: <オプション>">
  <div class="red">1</div>
  <div class="blue">2</div>
  <div class="green">3</div>
  <div class="purple">4</div>
</div>
```

## flex-direction: row；
何も指定しない場合、デフォルトはこれになります。
![スクリーンショット 2020-11-20 16.13.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/e872b134-ed38-a7eb-0a00-a0020e2dbf08.png)

## flex-direction: row-reverse;
![スクリーンショット 2020-11-20 16.13.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/115c8da6-49ae-b91c-3cb6-8cebc7195cc8.png)

## flex-direction: column;
![スクリーンショット 2020-11-20 16.14.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/71056b66-624f-ce55-468b-b19298505122.png)


## flex-direction: column-reverse;
![スクリーンショット 2020-11-20 16.14.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/7498ee13-768a-acdc-693a-0d72c018f255.png)


# justify-content
justify-contentは、コンテナ内の要素をflex-directionの向きに従って、<b>どのようにスペースを空けるか</b>を決めるプロパティです。

```html
<div class="container" style="display: flex; justify-content: <オプション>;">
  <div class="red">1</div>
  <div class="blue">2</div>
  <div class="green">3</div>
  <div class="purple">4</div>
</div>
```

## justify-content: flex-start;
![スクリーンショット 2020-11-20 16.27.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/fedd5d17-e143-eaff-7b5b-66115dff5132.png)

## justify-content: flex-end;
![スクリーンショット 2020-11-20 16.28.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/854d3721-a7c2-e095-5f5a-8c49125a3798.png)

## justify-content: center;
![スクリーンショット 2020-11-20 16.28.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/5d212c48-e3ca-4022-2f79-6bf2273a9be9.png)

## justify-content: space-between;
![スクリーンショット 2020-11-20 16.28.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/a8ee7399-cf1d-ed59-48d7-04fdb6eba62f.png)

## justify-content: space-around;
![スクリーンショット 2020-11-20 16.28.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/93899533-f91f-5cb3-847f-1cf27528f4a8.png)


## justify-content: space-evenly;
![スクリーンショット 2020-11-20 16.28.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/b26bcdfa-3104-dac5-b10f-58990413a0e7.png)

# align-items
align-itemsは、コンテナ内の要素をflex-directionの向きに対して<b>どの位置で配置するか</b>を決めるプロパティです。

```html
<div class="container" style="height: 100px; align-items: <オプション>;">
  <div class="red square">1</div>
  <div class="blue square">2</div>
  <div class="green square">3</div>
  <div class="purple square">4</div>
</div>
```

## align-items: flex-start;
![スクリーンショット 2020-11-23 14.54.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/18bb8a43-85c0-b08a-877c-2e718894d96e.png)

## align-items: flex-end;
![スクリーンショット 2020-11-23 14.54.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/75acabfd-d4f8-40b6-4fec-842758c22d71.png)

## align-items: center;
![スクリーンショット 2020-11-23 14.54.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/580615b2-3ab1-8f9c-7802-4a1ad1b9cd20.png)

## align-items: stretch;
![スクリーンショット 2020-11-23 14.55.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/b05d5cf5-08f0-65fa-ae0e-45321ce7ea0a.png)

## align-items: baseline;
![スクリーンショット 2020-11-23 14.55.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/85886d38-aea4-3442-a9e4-1d53e62057c2.png)

# align-content
align-contentは、ウィンドウ幅が縮められたときに、コンテナ内の要素を<b>どのように折り返すか</b>を決めるプロパティです。

```html
<div class="container" style="display: flex; flex-wrap: wrap; align-content: <オプション>;">
  <div class="red rectangle">1</div>
  <div class="blue rectangle">2</div>
  <div class="green rectangle">3</div>
  <div class="purple rectangle">4</div>
</div>
```

## align-content: flex-start;
![スクリーンショット 2020-11-23 15.10.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/96541c56-2421-22ef-304c-eab8943ad9ad.png)


## align-content: flex-end;
![スクリーンショット 2020-11-23 15.10.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/cd05e846-ef5d-bf36-a3e8-bc3274adc66e.png)


## align-content: center;
![スクリーンショット 2020-11-23 15.10.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/dbf4b523-e50b-de96-3838-93dc26a0755e.png)


## align-content: stretch;
![スクリーンショット 2020-11-23 15.11.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/a149e738-9750-d8d6-39c2-331974985281.png)


## align-content: space-between;
![スクリーンショット 2020-11-23 15.11.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/0f5c8d7c-c7c7-9a21-8ff2-b33776a41ae4.png)


## align-content: space-around;
![スクリーンショット 2020-11-23 15.11.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/9350f791-c2ef-8a59-895a-ef14832aeb11.png)


# flex-wrap
flex-wrapはウィンドウ幅が縮められたときに、コンテナ内の要素を<b>複数行にするかどうか</b>を決めるプロパティです。

```html
<div class="container" style="display: flex; flex-wrap: <オプション>;">
  <div class="red rectangle">1</div>
  <div class="blue rectangle">2</div>
  <div class="green rectangle">3</div>
  <div class="purple rectangle">4</div>
</div>

```

## nowrap;
![スクリーンショット 2020-11-23 15.25.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/2ba35720-8823-5650-542b-a1b0653e0f8f.png)

## wrap;
![スクリーンショット 2020-11-23 15.26.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/3f438e12-cb37-687f-8518-7fe9ed5d9a0b.png)

## wrap-reverse;
![スクリーンショット 2020-11-23 15.26.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/72543814-13a6-7465-214f-bb75e9d23d76.png)

# コンテナ内の一部の要素の配置
一部の要素だけ配置を変えたい場合のプロパティは、order, flex-grow, flex-shrink, align-selfなどがあります。

# order
orderはHTML要素の記述する順番は変えずに、表示順を変えるプロパティです。
下のような書き方をすると、2番目の要素 (青い箱) が4番目に移ります。

```html
<div class="container" style='display: flex;'>
  <div class="red rectangle">1</div>
  <div class="blue rectangle" style="order: 4">2</div>
  <div class="green rectangle">3</div>
  <div class="purple rectangle">4</div>
</div>
```

![スクリーンショット 2020-11-23 15.30.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/d8dc972d-a1f7-3385-9a5b-c1aeb693c139.png)


# flex-glow
flex-glowはコンテナ内に隙間があったときに、その隙間を各要素がどの比率で占有するか設定するプロパティです。

```html
<div class="container" style='display: flex;'>
  <p class="red" style="flex-grow: 0; padding: 12px; text-align: center;">1</p>
  <p class="blue" style="flex-grow: 0; padding: 12px; text-align: center;">2</p>
</div>
```

![スクリーンショット 2020-11-23 15.39.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/f2a175fc-ded4-3e88-2f9d-264f87100656.png)

```html
<div class="container" style='display: flex;'>
  <p class="red" style="flex-grow: 1; padding: 12px; text-align: center;">1</p>
  <p class="blue" style="flex-grow: 1; padding: 12px; text-align: center;">2</p>
</div>
```

![スクリーンショット 2020-11-23 15.44.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/f2d25f37-825d-e73d-04f2-cb156e45ba3a.png)


```html
<div class="container" style='display: flex;'>
  <p class="red" style="flex-grow: 1; padding: 12px; text-align: center;">1</p>
  <p class="blue" style="flex-grow: 1; padding: 12px; text-align: center;">2</p>
  <p class="green" style="flex-grow: 2; padding: 12px; text-align: center;">1</p>
</div>
```

![スクリーンショット 2020-11-23 15.44.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/854ca4c0-dfc9-5de2-324b-fd7dd893095b.png)



# flex-shrink
flex-shrinkはウィンドウを縮めるときに、どの比率で縮めるかを指定できるプロパティです。

```html
<div class="container" style='display: flex;'>
  <p class="red rectangle" style="flex-shrink: 0;">0</p>
  <p class="blue rectangle" style="flex-shrink: 1;">1</p>
  <p class="green rectangle" style="flex-shrink: 2;">2</p>
  <p class="purple rectangle" style="flex-shrink: 1;">1</p>
</div>
```

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/38fdcaf2-3699-c311-1318-5e688181a4c3.gif)


# align-self
align-selfは任意の要素の位置を個別に設定できるプロパティです。

```html
<div class="container" style="display: flex; align-items: flex-start;">
  <p class="red rectangle">red</p>
  <p class="blue rectangle" style="align-self: center;">blue</p>
  <p class="green rectangle">green</p>
</div>
```

![スクリーンショット 2020-11-23 16.06.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/581bf3ab-b9ea-3a47-26b8-a45a321ebdb4.png)


# 具体例
上記で説明したFlexboxの具体例をみていきます。

## 例1. 中央とそのすぐ左への配置
緑をウィンドウの中心におき、そのすぐ左に赤を配置するレイアウトを考えます (上下の要素は目安で入れただけなので、無視してください)。
![スクリーンショット 2020-11-23 16.27.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/40d9c2f6-b452-181b-0aec-f94be7d15fd9.png)

<details>
<summary>解答例 (他の解答例も募集中)</summary>
<div>

```html
<div style="display: flex;">
  <div style="flex-grow: 1; width: 100%; display: flex; justify-content: flex-end;">
    <p class="red square">中心すぐ左</p>
  </div>
  <div class="green square" style="flex-grow: 0; width: 150px;">中心</div>
  <div style="flex-grow: 1; width: 100%;"></div>
</div>
```
</div>
<details>


## 例2. 右側にメニューとそれ以外の範囲 
右側にメニューやアイコンなどがあって、左側はそれ以外のものを配置するレイアウトを考えてみます。
![スクリーンショット 2020-11-23 16.07.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/5c208101-273b-a403-0c4e-537e7300b779.png)

<details>
  <summary>解答例 (他の解答例も募集中)</summary>
  <div>

```html
<div style="display: flex;">
  <div class="red" style="display: flex; flex-grow: 1; padding: 12px;">
    左の範囲すべて
  </div>

  <div style="display: flex;">
    <p class="green">右</p>
    <p class="purple">メニュー</p>    
  </div>
</div>
```
  </div>
</details>


## 例3. 両端にメニュー
両端に2組みずつ要素を配置するレイアウトを考えてみます。
![スクリーンショット 2020-11-23 16.22.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/79a5ece3-8c88-2732-e87a-7c0411adfd4d.png)


<details>
<summary>解答例 (他の解答例も募集中)</summary>
<div>

```html
<div style="display: flex; justify-content: space-between;">
  <div style="display: flex">
    <p class="red">左</p>
    <p class="blue">メニュー</p>
  </div>
  <div style="display: flex;">
    <p class="green">右</p>
    <p class="purple">メニュー</p>    
  </div>
</div>
```
</div>
<details>

## 例4. フッター
ページの一番下にフッターを配置するレイアウトを考えます。
![スクリーンショット 2020-11-23 16.25.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/6d592238-aa92-7d60-60a4-869d7fc3381b.png)


<details>
<summary>解答例 (他の解答例も募集中)</summary>
<div>

```html
<div style="display: flex; flex-direction: column; justify-content: space-between; min-height: 100vh">
  <div>
    <h2 class="title">ページ下にフッター</h2>
    <div>
      下にフッターがあります。
    </div>    
  </div>

  <div class="red" style="display: flex; align-items: center; padding: 0 40px; height: 40px; width: 100%;">
    フッター
  </div>
</div>
```
</div>
<details>

## 例5. 小さくなり方が項目ごとに違うテーブルのような要素

タイトルの長さを固定にし、ウィンドウを小さくすると、概要, 備考 < 価格の順で小さくなるようなレイアウトを考えます。
![スクリーンショット 2020-11-23 16.45.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/5af1e30b-5faa-7a12-49ef-68b2297decbd.png)


<details>
<summary>解答例 (他の解答例も募集中)</summary>
<div>

```html
<div style="display: flex; height: 40px;">
  <div class="red" style="width: 260px; flex-shrink: 0;">タイトル</div>
  <div class="blue" style="width: 260px; flex-shrink: 1;">概要</div>
  <div class="green" style="width: 260px; flex-shrink: 4; min-width: 100px;">価格</div>
  <div class="purple" style="width: 260px; flex-shrink: 1;">備考</div>
</div>
```
</div>
<details>