header、footer、mainを組み合わせていい感じに表示する

# はじめに
世の中のほとんどのWebサイトにはヘッダーが使われていますし、フッターも多くのサイトで使われています。この記事ではそんな必要不可欠なヘッダーとフッターとメインをいい感じに配置する方法を紹介します。

# 理想
今回追い求めるのはヘッダーが画面のトップにあり、フッターが画面の一番下もしくはコンテンツの一番下にあるような配置です。
- 全コンテンツの高さが画面の高さより低いときは、メインの下部に隙間を作りフッターを画面の最下部に配置する
![スクリーンショット 2022-12-13 22.01.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591069/1addaa5b-c2cc-1526-a8d4-4cf4646f0bfa.png)
- 全コンテンツの高さが画面の高さよりも高いときは、フッターをメインの下に配置する
![スクリーンショット 2022-12-13 22.01.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591069/114b4244-e859-b876-14a3-bb2ea878e73d.png)
![スクリーンショット 2022-12-13 22.09.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591069/4bfa2bd4-a55d-5207-5140-756eaa66feb4.png)

下記ような配置にはならないようにCSSで装飾します。このような配置は誤っていると主張しているわけではなく、今回実装する配置ではないということを表しています。
- 全コンテンツの高さが画面の高さより低いときにフッターの下に隙間ができる
![スクリーンショット 2022-12-13 21.57.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591069/2e945eab-3128-0d46-030d-828f76d5f897.png)
-  全コンテンツの高さが画面の高さよりも高いときにフッターが画面下部に張り付く
![スクリーンショット 2022-12-13 22.27.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591069/ed484898-b6eb-4aa1-2b3b-4d28239e8008.png)

# gridを使って実装する
gridを使って実装する場合htmlは下のように構成します。
```html
<div>
  <header></header>
  <main></main>
  <footer></footer>
</div>
```
divにgridを与えてヘッダー、メイン、フッターをいい感じに配置していきます。
```css
div {
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-height: 100lvh;
}
```
`display: grid;`は対象のグリッドレイアウト化を行っています。
`grid-template-rows: auto 1fr auto;`は領域の縦方向の分割方法を決めています。frは他の方法で指定した部分以外の配分を決める単位です。frの配分はflexのgrowと同じ配分方法です。ここではautoによって自動で割り当てられた箇所以外の領域を占有するようになっています。最初のautoがヘッダー、1frがメイン、最後のautoがフッターに対応します。つまり、ヘッダーとフッターが領域の上と下に配置されて残りの部分をメインが占有するようになります。`grid-template-row`に対して横方法の分割方法を決める`grid-template-columns`もあり、`grid-template-columns: 100%`とすることで全コンテンツの横幅を画面サイズより大きくならないようにできます。
`min-height: 100lvh;`は縦幅の最小値を決めています。`100lvh`にすることで画面の縦幅が全コンテンツの最小サイズになリマス。これによって全コンテンツの高さが画面の高さより小さい時でもそれらが画面いっぱいを占めるようになります。さらに`grid-template-rows`の設定によりヘッダーが画面の上、フッターが画面の下、メインが残りの部分を占めるようになります。


<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="yLEdebg" data-editable="true" data-user="kokisakano" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/kokisakano/pen/yLEdebg">
  Untitled</a> by KokiSakano (<a href="https://codepen.io/kokisakano">@kokisakano</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

この方法はシンプルなのでおすすめです。

# flexを使って実装する
flexを使って実装する場合もhtmlは下のように構成します。
```html
<div>
  <header></header>
  <main></main>
  <footer></footer>
</div>
```
divにflexを与えてヘッダー、メイン、フッターをいい感じに配置していきます。
```css
div {
  display: flex;
  flex-direction: column;
  min-height: 100lvh;
}
main {
  flex-grow: 1;
}
```
行っていることはgridと同じです。
`display: flex;`は対象のフレックスレイアウト化を行っています。
`flex-direction: column;`は要素の並び方を上から下に並ぶようにしています。
`min-height: 100lvh;`は全コンテンツの高さの最小サイズを決めて、全コンテンツの高さが画面より小さかったとしても画面のサイズだけの領域を確保するようにします。
そして最後にmainに`flex-grow: 1`を与えています。これは、全コンテンツの高さが画面より小さいときにメインが残りの部分を占めるようにする設定です。

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="MWXMePw" data-editable="true" data-user="kokisakano" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/kokisakano/pen/MWXMePw">
  grid-content</a> by KokiSakano (<a href="https://codepen.io/kokisakano">@kokisakano</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

この方法はメインにもcssを記述する必要があるのでコンテンツごとにファイルを分割したときなどに見通しが悪くなります。gridを使えない理由がない限りはこちらは使わない方が良いと考えています。

# さいごに
ヘッダー、フッター、メインを並び替える方法をgrid、flexを使って紹介しました。簡単に設定できるので自分のWebサイトでもこのように設定したいと感じた方はぜひ採用してみてはいかがでしょうか。