見出し画像

position:fixedを使わずに、footerを画面最下部に固定するには? flexboxを使いこなす

はじめに

こんにちは、SHIFT の開発部門に所属しているKatayamaです。

footer 要素を画面最下部に固定して表示させたときには、ググってよく出てくる実装方法としては以下のように"position: fixed"と"bottom: 0"を使った実装だと思います(以下の実装は動く最小限のコードで、実際の実装としては不十分なのでご注意ください)。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <style>
      h1 {
        text-align: center;
      }
    </style>
  </head>

  <body>
    <header>
      <h1>Nav</h1>
    </header>
    <main>
      <h1>Main</h1>
    </main>
    <footer style="position: fixed; bottom: 0; width: 100%">
      <h1>Footer</h1>
    </footer>
  </body>
</html>

ただ、この方法だと以下の画像の赤色の枠で示している部分のように、親要素の内から飛び出た形で描画されてしまう事があります。ここで意図していた状況は、緑色で囲んでいる部分(親要素)内の最下部に赤色で囲んでいる部分が表示されるというものです。

このようになってしまう理由としては、"position: fix"を指定した要素は文書(HTML 全体)の通常のフローから除外され、ページレイアウト内に要素のための空間が作成されないためです。

そこで、"position: fix"を用いずに、flexbox を使いこなす事で footer 要素を画面の最下部に固定する事ができるので、今回はその方法についてみていきたいと思います。今回紹介する方法を使って実装すると、上記の赤色で囲んでいる部分も以下の画像のように親要素内に収まった形で最下部に固定するような実装ができるようになります(画像中の下矢印の意味については、以下の『"flex: auto"を使う』の項を参照頂くとその解説があります)。

flexbox を使いこなして footer 要素を画面の最下部に固定する

"margin-top: auto"を使う

1 つ目の方法として"margin-top: auto"を使う実装についてみていく。

以下のような実装だと単に全ての box 要素が上から順に並んでいる状態になるので、画像のように紫の斜め線が入っているエリアがすっぽり空いた状態になる。

<!DOCTYPE html>
<html lang="ja" style="height: 100%">
  <head>
    <style>
      h1 {
        text-align: center;
      }
    </style>
  </head>

  <body style="height: 100%; margin: 0">
    <div style="height: 100%; display: flex; flex-direction: column">
      <header>
        <h1>Nav</h1>
      </header>
      <main>
        <h1>Main</h1>
      </main>
      <footer>
        <h1>Footer</h1>
      </footer>
    </div>
  </body>
</html>

この状態で footer の要素に対し、"style="margin-top: auto""を追記すると、以下の画像のように flextbox の要素が自動的に縦方向に伸長し、footer 要素が画面最下部に固定されるようになる。

これは、flexbox 要素(flexbox 内にある要素)に自動マージンを適用すると、そのマージンは適用される方向に応じて、flex コンテナ内の余分なスペースを占有するように自動的に拡張される性質があるため。今回だと、footer という要素はその親である div で flexbox のスタイルを適用しているので、footer が flextbox 要素という事になり、これに自動マージントップ(margin-top: auto)を適用しているため、flexbox の上方向に対し box が拡張して余分なスペースを埋める挙動になっているのである。それにより footer が画面最下部に固定できる。

"margin-top: auto"を追記した HTML 全体は以下を参照。

<!DOCTYPE html>
<html lang="ja" style="height: 100%">
  <head>
    <style>
      h1 {
        text-align: center;
      }
    </style>
  </head>

  <body style="height: 100%; margin: 0">
    <div style="height: 100%; display: flex; flex-direction: column">
      <header>
        <h1>Nav</h1>
      </header>
      <main>
        <h1>Main</h1>
      </main>
      <footer style="margin-top: auto">
        <h1>Footer</h1>
      </footer>
    </div>
  </body>
</html>

・参考:Flexbox’s Best-Kept Secret

"flex: auto"を使う

今度は"flex: auto"を使った実装についてだが、ここでも『"margin-top: auto"を使う』で取り上げた以下の画像の状態からスタートする。

上記の画像の状態で、main に対して style="flex: auto"を追記する事で、以下の画像のように flextbox の要素が自動的に縦方向に伸長し、footer 要素が画面最下部に固定されるようになる(四角で囲んでいる部分は、h1 要素が占有しているエリアを示している)。

これは、"flex: auto"(="flex: 1 1 auto")という構文が、width・height を flexbox の空き領域を埋めるために自動的に調整(伸長したり、flexbox のコンテナーに合うように最小サイズまで収縮したり)させる構文であるため。今回だと上記の図のように矢印の部分が空き領域なのでそこを埋めるように自動的に調整してくれ、footer 要素が画面の最下部に固定されている状態になる。

※『はじめに』で矢印の描かれた図が出てきたが、その矢印はこの項で見てきた「空き領域を埋めるための自動的に調整」を意味している。

style="flex: auto"を追記した HTML 全体は以下を参照。

<!DOCTYPE html>
<html lang="ja" style="height: 100%">
  <head>
    <style>
      h1 {
        text-align: center;
      }
    </style>
  </head>

  <body style="height: 100%; margin: 0">
    <div style="height: 100%; display: flex; flex-direction: column">
      <header>
        <h1>Nav</h1>
      </header>
      <main style="flex: auto">
        <h1>Main</h1>
      </main>
      <footer>
        <h1>Footer</h1>
      </footer>
    </div>
  </body>
</html>

・参考:Sticky Footer

まとめとして

今回は flexbox を用いて footer 要素を画面の最下部に固定する方法を見てきた。CSS の基本的な使い方を知っていると『はじめに』で取り上げたような画面の最下部に固定したいが、親要素からはみ出て困るという事もなくなり、快適にフロントエンドの実装ができるのではないかと思う。


執筆者プロフィール:Katayama Yuta
SaaS ERPパッケージベンダーにて開発を2年経験。 SHIFTでは、GUIテストの自動化やUnitテストの実装などテスト関係の案件に従事したり、DevOpsの一環でCICD導入支援をする案件にも従事。 最近開発部門へ異動し、再び開発エンジニアに。座学で読み物を読むより、色々手を動かして試したり学んだりするのが好きなタイプ。


お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/