JavaScriptに関するお知らせ

SINCE2019
>
【CSS】ヘッダーとフッターを固定するレイアウトの比較

【CSS】ヘッダーとフッターを固定するレイアウトの比較



こんにちは!アドレスバーが画面下に来るレイアウトのブラウザに慣れないMizutani(@sirycity)です。ついにSafariも下にきた。

今日はWebサイトでもWebアプリでもよくある、ヘッダーとかフッターが固定されてるレイアウトを作るときの手法の比較です。比較っても2つしかないけど。

はじめに

こんなかんじのマークアップを想定します。どシンプル。

<header></header>
<main></main>
<footer></footer>

方法1:fixedで固定

position: fixed でヘッダーとフッターを固定します。超王道。cssもかんたん。

header {
  position: fixed;
  top: 0;
}
main {
  /* 特になし */
}
footer {
  position: fixed;
  bottom: 0;
}

長所

長所は簡単なところ。以上。基本的にはこっちでいいです。Webサイトとかならなおさら。

短所

短所は3つ。

まずmainに書かれた内容、とくに上端と下端の内容がヘッダーとフッターに被って見えなくなることがあります。なのでmainはこんな感じに調整が必要です。

header {
  position: fixed;
  top: 0;
  height: 1.5rem;
}
main {
  padding-top: 1.5rem;
  padding-bottom: 0.8rem;
}
footer {
  position: fixed;
  bottom: 0;
  height: 0.8rem;
}

もしくはヘッダーとフッターをスケルトンにしても良いかも。

header {
  opacity: .5;
}
footer {
  opacity: .5;
}

2つめ、スクロールバーがヘッダーとフッターの上に来ます。ちょっと直感的じゃないかも。

3つめ、positionを使うのでz-indexにちょっと気を遣う必要があります。たとえばmainをrelativeにして最前面に出したいコンポーネントをabsoluteにするとz-index付けなきゃfooterの下に潜ったりしちゃう。

方法2: 並列で縦に並べる

こんな感じ。

header {
  height: 2rem;
}
main {
  /* 注意! */
  height: calc(100vh - 2rem - 1rem);
}
footer {
  height: 1rem;
}

全部縦に並べるけど、mainの大きさを調整してちょうど1画面に収まるようにする方法です。

長所

fixedで固定するやつの短所が全部克服されています。

  • mainがヘッダーとフッターに被ることもなく
  • スクロールバーも被らず
  • z-indexも気にしなくてOK。

短所

最大の短所ですが、mainを調整して1画面にぴったり収めるのは超難易度です。↑のようにvhでは1画面にはなりません。vhの仕様ははっきり言って罠です。罪です。

【CSS】100vhは「一画面」ではないという罠

ぴったり1画面に収めるにはライブラリが必須です。こんな感じの。

react-div-100vh

vue-div-100vh

実際のマークアップだとこんな感じになります。react-div-100vhだとこんな感じ。

<Div100vh>
  <header></header>
  <main></main>
  <footer></footer>
</Div100vh>
header {
  height: 2rem;
}
main {
  height: calc(100% - 2rem - 1rem);
}
footer {
  height: 1rem;
}

得てして、こっちの方法はしっかりしてるけどめんどいです。

あともう1つ、mainが縦スクロールするパターンならoverflow-yを指定する必要があります。

main {
  overflow-y: scroll;
}

結論

こんな感じで使い分けると良いかと思います↓

  • フロントエンドのエコシステムに入ってない構成ならfixed
  • webサイトならfixed
  • webアプリ、特に縦スクロールが必要ない1画面の構成なら縦に並べる
  • その他はfixed

僕としては縦に並べる方法が好きなんですが、やはりvhの仕様が足を引っ張りますね。こればかりはしょうがないけどね。以上。



PREV
2021-09-29
【JS】Web制作でReact使う時によくやるループの書き方

NEXT
2021-10-16
GooglePayでVisaタッチを使う時に知っておきたい過酷な現実