フッター固定方法のあれこれをサンプル付きで解説
ウェブページのコンテンツが少なくて、フッターの下側に余白ができるといったことが稀にあります。これ、皆さんどうしてます?
今回は、フッターの下側に余白ができるような場面で、フッターを表示領域下部に固定する方法を紹介します。
フッターを固定する方法は、いくつも編み出されてきましたが、いずれも一長一短がありました。
よくあるフッターの固定方法
絶対配置でウェブページ下部に固定する
…
<style>
div {
box-sizing: border-box;
min-height: 100vh;
padding-bottom: 3em; /* フッターを配置するスペース */
position: relative;
}
footer {
height: 3em;
overflow: hidden;
position: absolute;
inset: auto 0 0;
}
</style>
…
<div>
…
<footer>
<p>Footer</p>
</footer>
</div>
…
この方法の欠点は、フッターの高さを決めておく必要があるという点です。絶対配置は通常のレンダリングフローから外れ、親要素や後続する要素に影響を与える「高さ」が消失してしまうためです。そのため、フッター内のコンテンツ量が不明確な場合には向きません。
絶対配置で表示領域下部に固定する
…
<style>
div {
box-sizing: border-box;
min-height: 100vh;
padding-bottom: 3em; /* フッターを配置するスペース */
}
footer {
height: 3em;
overflow: hidden;
position: fixed;
inset: auto 0 0;
}
</style>
…
<div>
…
<footer>
<p>Footer</p>
</footer>
</div>
…
この方法の欠点は、絶対配置でウェブページ下部に固定する場合と同様、フッターの高さを決めておく必要があるという点です。フッター内のコンテンツ量が不明確な場合には向きませんが、フッターをスクロールに追従させる一般的な方法でもあります。
フッターの前にある要素の高さを設定する
…
<style>
main {
min-height: 100vh;
}
</style>
…
<div>
…
<main>
<p>Content</p>
</main>
<footer>
<p>Footer</p>
</footer>
</div>
…
最もCSSコードの記述量が少なく、フッター内のコンテンツ量に制約はありません。欠点は、無駄に垂直方向のスクロールが発生してしまう点と、高さを設定できる要素が前になければならない点です。デザインによっては使えないかもしれません。
フッター上部のマージンを自動伸縮させる
…
<style>
div {
display: flex;
flex-flow: column;
min-height: 100vh;
}
footer {
margin-top: auto;
}
</style>
…
<div>
…
<footer>
<p>Footer</p>
</footer>
</div>
…
通常、垂直マージンに auto
(自動伸縮) を設定しても機能しませんが、親要素に display:flex;
を設定して、フレックスアイテムとして扱われると機能するようになります。フッター内のコンテンツ量に制約はなく、無駄に垂直方向のスクロールも発生しないので、かなり理想的と言えますが、親要素はフレックスコンテナ、兄弟要素はフレックスアイテムになってしまうので、大袈裟な感じは否めません。
新しいフッターの固定方法
…
<style>
div {
min-height: 100vh;
}
footer {
position: sticky;
top: 100vh;
}
</style>
…
<div>
…
<footer>
<p>Footer</p>
</footer>
</div>
…
相対配置の position:sticky;
を使用した方法になります。フッター内のコンテンツ量に制約はなく、垂直方向のスクロールも必要な場合しか発生せず、親要素や兄弟要素への影響も最小限です。これまでのフッターの固定方法にあった欠点が全くありません。
CodePen による実際の表示
新しいフッターの固定方法でスクロールに追従させたい場合
新しいフッターの固定方法を利用しつつ、position:fixed;
のようにスクロールに追従させたい場合、top:100vh;
を bottom:0;
に変更すれば実現できそうに思えますが、できません。
スクロールが発生する場合は、表示領域下部に固定され追従しますが、スクロールが発生しない場合は、表示領域下部に固定されず、フッターの下側に余白ができてしまいます。
そこで、フッター上部のマージンを自動伸縮させる方法と組み合わせます。
…
<style>
div {
display: flex;
flex-flow: column;
min-height: 100vh;
}
footer {
margin-top: auto;
position: sticky;
bottom: 0;
}
</style>
…
<div>
…
<footer>
<p>Footer</p>
</footer>
</div>
…
注意点としては、フッターの高さが表示領域 (100vh
) を超える場合、フッター上部が表示領域の外側にはみ出てしまいます。フッター内のコンテンツ量が多くなる場合は、max-heightプロパティとoverflowプロパティを追加しておくと良いです。
CodePen による実際の表示
[おまけ] 隠れる固定ヘッダー
…
<style>
header {
margin-bottom: 100vh;
position: sticky;
top: 0;
}
header + * {
margin-top: -100vh;
}
</style>
…
<div>
<header>
<p>Header</p>
</header>
<main>
<p>Content</p>
</main>
…
</div>
…
スクロールに追従するヘッダーはフッターよりも簡単にできます。そこに、margin-bottom:100vh;
と margin-top:-100vh;
を追加すると、一番下までスクロールしたとき、ヘッダーが隠れるようになります。
CodePen による実際の表示
〆
要素を特定の位置に固定するには、position:absolute;
や position:fixed;
ばかり使われてきましたが、少し工夫すれば、position:sticky;
の方が便利ですよね。