【CSS】flex-growを使おう

# はじめに

## 問題

早速ですが、こんな時どう実装しますか？

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/a1da0886-a8db-8f1c-aa91-322565947631.png" width=500 />

## 少し前までの私

Headerは、`height: 100px`で`padding: 10px`ということは上下のpaddingを足して120px
Footerが`height: 50px`で`padding: 5px`だから同様に考えて、60px
合わせるとMain以外の部分が、`180px`で、
Mainのpaddingが10pxだから、上下で`20px`必要で、

```css
main {
  height: calc(100vh - 200px)
}
```

ふう...

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/4e635f37-8edf-0032-46fd-e6df685cb7ac.png" width=300 />

### 問題点

- HeaderとFooterの高さが変わると計算し直す必要がある
- HeaderやFooterが動的に高さが変わる場合、JSで高さを適用しないといけない
- etc...

そこで**flex-grow**を紹介します。

**flex-grow**の紹介に入る前に、**Flexbox(フレックスボックス)**について語ります

# Flexbox

**Flexbox**は、主に次の2つの部分から成り立っています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/65ec7b27-49e2-2f31-7c0c-85a82c39b626.png)

**flex container(フレックスコンテナ)**
これはflexアイテムを包含する要素で、アイテムのレイアウトを制御します。

**flex item(フレックスアイテム)**
これらはコンテナ内の個々の要素で、コンテナによってその配置が制御されます。


例えば、**flex container**に`justify-content`というプロパティを設定すると↓のように配置を設定することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/f5c2066c-f0cd-a22f-21db-ed52e294d411.png)

次に、本題のflex-growについてです

# flex-grow

> flex-growはCSSのプロパティで、フレックスアイテムの主軸方向の寸法のフレックス伸長係数を設定します。
> (mdn web docsより)

...よく分からないですね。頭が痛くなります。

**フレックス伸長係数** → **どれだけ伸びることができるか** → **どれだけ成長できるか**

と考えてみてください。

すると、先ほどの説明文が、

> flex-growはCSSのプロパティで、フレックスアイテムの主軸方向にどれだけ成長できるかを設定します。

という風に書き換えられます。

ちょっと分かるような気がしてきました。

次に、 **成長って何だろう？** と考えてみます


Flexboxを説明した図で言うと、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/e9302c2f-5187-1c9e-dc79-f464a3023266.png)

このオレンジの部分が成長できる余地です。

flex-growを使うと、**flex-item**に対する、このオレンジの部分の占有率を設定することができます。

これの**B**に`flex-grow: 1`を設定すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/056e1da9-6933-e67d-c599-9af838d17320.png)

このようにオレンジ部分の余地をBが占領します

**C**にも`flex-grow: 1`を設定すると、、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/62e09a11-d37f-a0e2-c58f-54bb05f01910.png)

こうなります

最後に**B**に`flex-grow: 3を`設定してみると、、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/ef62978d-52b5-1a6a-cee8-565fd9265ab9.png)

こうなります
Bがちょっと伸びて、Cが縮まりました。

何が起きたのか図で説明します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/019c2c7f-7c2e-fcbb-3f6f-ea52e7f3d6c5.png)
※アルファベットの下のパーセントは余地の占有率を表しています。


このように、flex-growを設定すると、成長幅の占有率を設定することができます。


じゃあ...

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/a1da0886-a8db-8f1c-aa91-322565947631.png" width=500 />

これをflexboxを使って実装してみます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/01aeda38-1c96-8686-cb4d-ed232c139f0b.png)

```html:index.html
  <body>
    <header>Header</header>
    <main>Main</main>
    <footer>Footer</footer>
  </body>
```

```css:index.css
body {
  display: flex;
  /* flex-directionをflex containerに設定して、主軸方向を縦にしています */
  flex-direction: column;
  height: 100vh;
}

header {
  height: 100px;
  padding: 10px;
  background-color: #c9c9c9;
}

main {
  padding: 10px;
  /* 1/1 = 100% 余地の独占状態 */
  flex-grow: 1;
  background-color: #dae8fc;
}

footer {
  height: 50px;
  padding: 5px;
  background-color: #c9c9c9;
}
```

最初にやった面倒な計算が無くなり、スッキリしましたね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/ae72e35a-4b5e-b094-df00-4565a4e99a7b.png)