文系のIT勉強メモ

勉強中のメモと、インフラの覚書き

中身が少なくてもfooterを下に。

  • 中身が少なくてもfooterを下部にしたい
  • でも、下に固定するわけじゃなくて、中身が多ければその中身よりも下にいかせたい。スクロールしてから出てきてほしい(なんとなく狭い感じがするからね)

よくある構成、当たり前の要望だと思うけど、bootstrapでそれが難しくて、検索しても何か古いのかな?と思うやり方しかなくて。サンプルから、footerの固定に関係してそうな部分を、ひとつずつ削除したり追加したりして、最低限を割り出したので、メモかねて書いておく。

f:id:suika_daisuki:20201030003904p:plain

bootstrap公式のサンプル

bootstrapのサンプルのなかで、footerに関するものは2つ。

これらは中身にいろいろ入れてみると私の要望する前提条件をかなえている。

早速だけど最低限はこれ。

footerに「mt-auto」をつけるか、mainとなるところを「flex-grow-1」をつけるかどちらか。背景色つけるときにflex-grow-1つけるほうが良い.

最低限といいつつ、ヘッダーとメインも。

ヘッダー
  • 帯は全幅だけど、中身(左にサイトタイトル、右側にメニュー)はcontainerの幅におさめる。
  • sticky-topにしてみた。メニューいれるなら固定されたほうがいいし、かと言ってfixed-topだと、下に入れたいメインがその背面にもぐって、padding-topで調整しないといけなくなるのが面倒だから。
メイン
containerの幅。

 

<!DOCTYPE html>
<html lang="ja" class="h-100">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ページタイトル | サイトタイトル</title>
        integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
</head>

<body class="d-flex flex-column h-100">
    <header class="bg-dark navbar sticky-top">
        <div class="container">
            <a class="navbar-brand" href="#">
                サイトタイトル
            </a>
            <nav>
                <ul class="nav">
                    <li class="nav-item">
                        <a class="nav-link active" href="#">Active</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">Link</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">Link</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link disabled" href="#">Disabled</a>
                    </li>
                </ul>
            </nav>
        </div>
    </header>

    <div class="container flex-shrink-0 shadow">
        めいん
    </div>

    <footer class="mt-auto bg-dark py-2 text-center">
        <div class="container">
            <small class="text-muted">フッター
            </small>
        </div>
    </footer>

</body>

</html>

解説

古いのも混ざっているのか、ドキュメントで見つけられなかったのもあるけど、それでも消すと動作しなかったので必須と判断した。この構成をつくるのに必要なのは以下。

  • htmlとbodyにclass名「h-100を適用:どちらをなくしてもだめ。両方必要。ドキュメントで見つけられないけど100vh(高さ100%)っぽい。
  • bodyにはh-100のほかに、「d-flex」「flex-column」も必要:bootstrapってgridといいつつflexでしょって思ってたけど、flexにするためのclass「d-flex」をつける。「d-flex」でヘッダー、メイン、フッターが横に1段3カラムで並んじゃうのを「flex-column」で縦に並ぶようにする。
  • メインとなる枠に「flex-shrink-0:htmlとbodyのh-100がたぶん100vhで、ヘッダーとフッター以外のすきまをメインの高さとするための設定。サンプルだと縮めるshrinkが使われてる(flex-shrink-0)。縮めるじゃなくて、どこまで伸びるかでしょ?とflex-grow-1でやってたら、他のブラウザはそれでもいいんだけどIEで崩れた。shrinkだと背景色つけたときにfooterまで届かないことになって、おかしいと思ったけど、growよりうまくいってる。IEで。
  • 上にも書いたけど、まんなかのコンテナを伸縮させるのではなく、footerのmargin-topをautoにすることでfooterを下にやってもいいけど、それだとmainの範囲は短いままなので、背景色をつけたときにおかしくなる。
bootstrap公式ドキュメントの該当箇所

なんなんだろうね

footerの下部固定について検索すると「footer」っていうclass名を使う方法を書いてるところもあったけど、動作しなかった。古いのかな。ドキュメントにも記載ない。

ちなみに私は最近はgridをareaで使うのが気に入ってるから、bootstrapじゃなかったらgridでこんな感じでやる。

body{
    min-height:100vh;
    displaygrid;
    grid-template:
    "header header header header"
    "... aside main ..."1fr
    "footer footer footer footer"
    /1fr 320px minmax(400px,800px1fr;
}

grid-areaは記載省くけど、まあそのまんまだから察してください。

モバイル対応、細部のデザインをbootstrapにまかしたら、footerのとこのためにこのgridを適用しようとしたら、混ざるとおかしくなるのか、レイアウトが崩れた、、、ので。それでbootstrapでのfooter固定を探す必要があったのです。

逆に細部だけbootstrapで大枠のレイアウトはgrid-areaでやろうと思ったら、ヘッダーとフッター全幅のときのレイアウトが難しくて解決に至らなかった。シンプルに書く方法が。メディアクエリで幅ごとに設定するくらいなら大枠もbootstrap使ったほうがいいし。

本当は上に書いた例で「minmax(400px,800px)」って書いたとこを、1frにできたらいいのに。でも不定の幅の左右を、右と左で同じ割合で割り振るのに1fr使っちゃうと、mainの幅として1fr使えなくなっちゃう。あとヘッダーは全幅にしつつも中身はmax幅決めておきたかったから、そういうのもgrid-areaでシンプルに設定できない。

grid-areaは全幅の要素がないか、全部が全幅だったらいいんだろうけど、全幅とmax幅を設定したい要素が全体レイアウトのなかで入り混じってるときにはシンプルに書けないのかなと思う。

また試行錯誤して良い書き方みつけたいなと思う。grid-areaが大好きだから。