フッター固定方法のあれこれをサンプル付きで解説

ウェブページのコンテンツが少なくて、フッターの下側に余白ができるといったことが稀にあります。これ、皆さんどうしてます?

今回は、フッターの下側に余白ができるような場面で、フッターを表示領域下部に固定する方法を紹介します。

フッターを固定する方法は、いくつも編み出されてきましたが、いずれも一長一短がありました。

よくあるフッターの固定方法

絶対配置でウェブページ下部に固定する

…
<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 による実際の表示

See the Pen Fixed footer by nov (@numerofive) on 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 による実際の表示

See the Pen Floating footer by nov (@numerofive) on 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 による実際の表示

See the Pen Floating header by nov (@numerofive) on CodePen.

要素を特定の位置に固定するには、position:absolute;position:fixed; ばかり使われてきましたが、少し工夫すれば、position:sticky; の方が便利ですよね。

関連記事