コンテンツの量が少ない場合や、解像度の高いディスプレイでみた場合、
いわゆるスクロールバーが出ない状態では、フッタが上にせり上がった状態になり、下へ隙間ができます。
この解決方法でよく見かけるCSS対策がこの2つ。
- bodyに
display: flex;
を設定する - htmlとbodyへ
min-height: 100%;
を設定する
しかし、これらを安直に設定してみたところ
Internet Explorer 11とiPhoneのSafariでつまづいたので
ポイントをまとめてみました。
See the Pen Footer on bottom of page by webdev (@webdev-jp-net) on CodePen.0
スマートフォン確認用:
Footer on bottom of page サンプル
IEでmin-height
が効かない問題
IEはdisplay: flex;
にmin-height
が効かない仕様です。
このように設定して、できた!と思っていたら、IEでは効いていませんでした。
html { min-height: 100%; } body { min-height: 100%; display: flex; flex-direction: column; } body > footer { margin-top: auto; }
IE対策は flexの入れ子
html { min-height: 100%; } body { display: flex; } body > #page { display: flex; flex-direction: column; min-height: 100%; } #page > footer { margin-top: auto; }
display: flex;
が効いたbodyの中にdivを追加して、flexbox
を入れ子にするとIEでもhtmlと同じ高さ(表示範囲の高さ)までdivがフィットしてくれます。
入れ子にしていると、bodyにはmin-heightを設定していなくても大丈夫です。
iPhoneのSafariは100vhが画面外にはみ出す
iPhoneのSafariは、内容が少なくスクロールがない場合は
ブラウザの底辺に表示されているメニューバーがせり出しています。
この影響で、実際に見えている範囲の高さは100vh - メニューバーの高さ
になっていて、min-height: 100vh;
を設定していると
フッタが見切れて常にスクロールできるようになってしてしまいます。
表示範囲の高さは window.innerHeight
で取得
2019年10月現在は、残念ながらスタイルシートだけではメニューバーに影響されない画面の高さを取得することができません。
iPhone Safariでもフッタを画面下ぴったりに表示させるなら、JavaScriptで調整します。
まず、フッタの直接の親となる要素(例では#page)には
スタイルシートでmin-height: 100vh;
を設定しておきます。
body > #page { display: flex; flex-direction: column; min-height: 100vh; }
iPhone Safariの表示範囲の高さはwindow.innerHeight
で取得できます。
var $page = document.getElementById('page'); if ($page.clientHeight != window.innerHeight) $page.style.setProperty('min-height', window.innerHeight + 'px');
#pageのclientHeight > window.innerHeight
なら、表示範囲の高さが100vhと一致していないことになるのでmin-height
の値をwindow.innerHeight
(=表示範囲の高さ)に書き換えています。
このとき、カクつく違和感を軽減するため
スタイルシートでmin-height: 100vh;
を設定するついでにtransition
のmin-height
も設定すると
アニメーションしながら縮むので自然になります。
body > #page { display: flex; flex-direction: column; min-height: 100vh; transition: min-height .2s; }
スマホを回転したときや、ウィンドウサイズを変更したときにも対応するなら
resizeイベントでふたたびサイズ調整を実行するよう設定します。
var $page = document.getElementById('page'); window.addEventListener('resize', setMinHeight, false); setMinHeight() { if ($page.clientHeight != window.innerHeight) $page.style.setProperty('min-height', window.innerHeight + 'px'); };
そのほか、ヘッダとフッタの色が同じならば
bodyの背景色も同じ色にそろえ、$pageの背景色を本文の背景色に設定すると
ページの最初(最後)までスクロールしたときのバウンスでbodyとヘッダ、フッタとの境界がとけて自然になります。
サンプルでは、ヘッダ、フッタ、bodyをグレーに、本文背景を白にしています。
Footer on bottom of page サンプル