jQueryでフッターをページの長さに合わせてページ下部に固定する方法

##1.はじめに
本記事は**フッターをページ長さに合わせてページ下部に固定する**方法について自分の勉強記録も兼ねて執筆します。

ちなみに**footerFixed.js**というライブラリを使えば簡単にできるみたいですが（笑）、本記事ではそれは使わずに実装していきます。

**footerFixed.js**の使い方は[こちら](https://www.webantena.net/javascriptjquery/fixed-footer-with-jquery/)

##2.目的
フッターをページ長さに合わせてページ下部に固定する

##3.コード
簡単ですが、下がコード例です。
今回は簡略下のためcss、JavaScriptをhtmlファイル内に書き込んでいます。（実際は別ファイルで管理する方が良いと思います）

```html:sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <style>
        body {
            color: #fff;
            text-align: center;
            width: 50%;
            margin: 0;
            padding: 0;
        }
        header {
            background: blue;
            height:100px;
            line-height: 100px;
        }

        section {
            background-color: #444;
            height: 200px;
            line-height: 200px;
        }

        footer {
            background: orange;
            width: 50%;
            height: 100px;
            line-height: 100px;
        }

    </style>
    <header>ヘッダー</header>
    <section>メインセクション</section>
    <footer id='footer'>フッター</footer>

    <script src='https://code.jquery.com/jquery-3.4.1.min.js'></script>

    <script>

        $(function(){
        //フッターを最下部に固定
            var $footer = $('#footer');
            if(window.innerHeight > $footer.offset().top + $footer.outerHeight() ) {
                $footer.attr({'style': 'position:fixed; top:' + (window.innerHeight - $footer.outerHeight()) + 'px;' });
            }
        })

    </script>
</body>
</html>
```



Google Chromeで表示すると下のようになります。
![スクリーンショット 2019-12-14 21.35.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512695/ce61026c-c218-9bc7-dfd8-c4ca8d3e6dc8.png)

ちなみにcssで要素の**heightとline-heightの数値を揃える**と文字を**上下中央揃え**に出来ます。
（結構使えます）


今回のメインとなるコードはその内、下のコードです。

```html:sample.js

 <script>
        
        $(function(){
        //フッターを最下部に固定
            var $footer = $('#footer');
            if(window.innerHeight > $footer.offset().top + $footer.outerHeight() ) {
                $footer.attr({'style': 'position:fixed; top:' + (window.innerHeight - $footer.outerHeight()) + 'px;' });
            }
        })

    </script>
```
##4.コードの解説
では上記のコードを解説していきます。

**❶`var $footer = $('footer');`**

まず`var $footer = $('#footer');`でid='footer'のDOMを取得します。
`<footer class='footer'>フッター</footer>`だったら`var $footer = $('.footer');`となります。
id属性とclass属性をつけたセレクタの指定の仕方はcssと同じなのでここでは割愛します。

DOMについては[こちら](https://eng-entrance.com/what-is-dom)

簡単にいうとfooter要素を取得したと考えてもらえたらOKです。

フッターのDOMを取得したのでフッターをjavaScript(jQuery）で操作する準備が出来ました。

**❷`if(window.innerHeight > $footer.offset().top + $footer.outerHeight() ) `**

まず上記コードの意味を簡単に言うと**表示画面(window)の長さがフッターの下端までの距離より長い場合**です。

なるべく詳しく説明していきます。

図で表すとこんな状態です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512695/8727597c-c0f5-f5ce-5f13-6ce8e9286141.png)



上図のように表示画面の高さよりフッター下端までの距離が短い場合、本記事で解説している`<script>〜</script>`のコードがなければ表示画面の途中にフッターが表示されることになります。

ですので、このような場合にフッターの位置をページ最下部に固定したいのでif文を使っています。

`.innerHeight`は要素のpaddingを含んだ高さを取得するメソッド
`.outerHeight`は要素のborder、paddingを含んだ高さを取得するメソッド
`.offset().top`はその要素の上端の位置を取得するメソッド

です。

高さを取得するメソッドの詳しい説明は[こちら](https://qiita.com/ypyp/items/c4b76e85f32b1f0cd577)
.offset()メソッドの詳しい説明は[こちら](https://www.flatflag.nir87.com/offset-1167#offset)


**❸` $footer.attr({'style': 'position:fixed; top:' + (window.innerHeight - $footer.outerHeight()) + 'px;' });`**

いよいよフッターをページ最下部へ固定していきましょう。

まず、`.attr`は要素の属性を取得、変更、追加することのできるメソッドです。

.attrメソッドについては[こちら](https://qiita.com/gestalt/items/b5317984015a2bb6b745)

style属性を追加して、まず固定するために`position: fixed;`を指定します。
`top:〜`で固定場所を指定します。
`(window.innerHeight - $footer.outerHeight()) + 'px;'`で表示画面の下端からフッターのheightを差し引いた位置を指定しています。

つまり、**ページ長さに応じて自動でフッターがページ最下部に固定される**ということです。

コード解説は以上です！！

※ちなみにcssファイルを別で準備してhtmlファイルに読みこませるようにしていたら.cssメソッドでも実装できるかもです。


##5.positon:fixed;との違い
みなさんに質問です。
**「フッター固定したいならヘッダーを上部固定するみたいにcssで`position:fixed;`を指定すればできるんじゃない？」**って思いませんでしたか？
僕は当時は思いました。（みなさん思わないようでしたらすみません）

ですが、フッターに直接`position: fixed;`を指定した時に困ることがあります。

それについて追加で説明していきます。

まず、WEBサイトをつくる時って1ページで完成することもありますが、複数ページで構成されることの方が多いのではないでしょうか？

複数ページで同じフッターをページ下部に表示することになるので、同じcssを適用することになります。
そのページごとにposition:fixed;の座標をcssで指定しなければならなくなります。

例えば、
ヘッダー、メインセクション、フッターの高さがそれぞれ50px、300px、50pxの場合、

```css:sample.css

footer {
    position:fixed;
    top:350px;
}
```

とすれば、以下の通り綺麗にページ下部に固定できますよね。（図は不要と判断しましたのでイメージしてください）

しかし、別のページでメインセクションのheightが500pxになった場合、同じsample.cssを適用すると下の図のようにメインセクションとフッターが重なってしまいますよね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512695/8768b0c3-7510-ba46-da2b-05342cf248c1.png)


このような場合

footer要素に`<footer class='footer-1 footer-2'`のように複数のclass属性値をつけてcssを分ける必要があります。

これが10ページくらいになるとすると、class属性値も10個つけなればなりません（笑）

控え目に言って**めちゃくちゃメンドクさい**です。

プログラミングはめんどくさいことを効率化できるというメリットがあるのにめんどくせいことはできるだけやめましょう。

##6.最後に
本記事ではjQueryを用いて**ページ長さに合わせてフッターをページ最下部に固定する方法**について説明しました。

最後にもう一度ソースコードを載せておきます。

```html:sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <style>
        body {
            color: #fff;
            text-align: center;
            width: 50%;
            margin: 0;
            padding: 0;
        }
        header {
            background: blue;
            height:100px;
            line-height: 100px;
        }

        section {
            background-color: #444;
            height: 200px;
            line-height: 200px;
        }

        footer {
            background: orange;
            width: 50%;
            height: 100px;
            line-height: 100px;
        }

    </style>
    <header>ヘッダー</header>
    <section>メインセクション</section>
    <footer id='footer'>フッター</footer>

    <script src='https://code.jquery.com/jquery-3.4.1.min.js'></script>

    <script>

        $(function(){
        //フッターを最下部に固定
            var $footer = $('#footer');
            if(window.innerHeight > $footer.offset().top + $footer.outerHeight() ) {
                $footer.attr({'style': 'position:fixed; top:' + (window.innerHeight - $footer.outerHeight()) + 'px;' });
            }
        })

    </script>
</body>
</html>

```

ご存知の方はたくさんいると思いますが、この機能はかなり便利（と思っています）なので是非使ってみて欲しいなと思います！

今回は以上です。

※コメント、ご指摘等ありましたら何でも受付けておりますので気軽にコメントいただけたらと思います。