はじめに
問題
早速ですが、こんな時どう実装しますか?
少し前までの私
Headerは、height: 100px
でpadding: 10px
ということは上下のpaddingを足して120px
Footerがheight: 50px
でpadding: 5px
だから同様に考えて、60px
合わせるとMain以外の部分が、180px
で、
Mainのpaddingが10pxだから、上下で20px
必要で、
main {
height: calc(100vh - 200px)
}
ふう...
問題点
- HeaderとFooterの高さが変わると計算し直す必要がある
- HeaderやFooterが動的に高さが変わる場合、JSで高さを適用しないといけない
- etc...
そこでflex-growを紹介します。
flex-growの紹介に入る前に、**Flexbox(フレックスボックス)**について語ります
Flexbox
Flexboxは、主に次の2つの部分から成り立っています
flex container(フレックスコンテナ)
これはflexアイテムを包含する要素で、アイテムのレイアウトを制御します。
flex item(フレックスアイテム)
これらはコンテナ内の個々の要素で、コンテナによってその配置が制御されます。
例えば、flex containerにjustify-content
というプロパティを設定すると↓のように配置を設定することができます。
次に、本題のflex-growについてです
flex-grow
flex-growはCSSのプロパティで、フレックスアイテムの主軸方向の寸法のフレックス伸長係数を設定します。
(mdn web docsより)
...よく分からないですね。頭が痛くなります。
フレックス伸長係数 → どれだけ伸びることができるか → どれだけ成長できるか
と考えてみてください。
すると、先ほどの説明文が、
flex-growはCSSのプロパティで、フレックスアイテムの主軸方向にどれだけ成長できるかを設定します。
という風に書き換えられます。
ちょっと分かるような気がしてきました。
次に、 成長って何だろう? と考えてみます
Flexboxを説明した図で言うと、
このオレンジの部分が成長できる余地です。
flex-growを使うと、flex-itemに対する、このオレンジの部分の占有率を設定することができます。
これのBにflex-grow: 1
を設定すると
このようにオレンジ部分の余地をBが占領します
Cにもflex-grow: 1
を設定すると、、、
こうなります
最後にBにflex-grow: 3を
設定してみると、、、
こうなります
Bがちょっと伸びて、Cが縮まりました。
何が起きたのか図で説明します。
※アルファベットの下のパーセントは余地の占有率を表しています。
このように、flex-growを設定すると、成長幅の占有率を設定することができます。
じゃあ...
これをflexboxを使って実装してみます
<body>
<header>Header</header>
<main>Main</main>
<footer>Footer</footer>
</body>
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;
}
最初にやった面倒な計算が無くなり、スッキリしましたね!