質問するログイン新規登録
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

1126閲覧

HTMLのページで、コンテンツが短い時だけフッターをページの一番下に固定したい

donkuri

総合スコア81

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

1クリップ

投稿2021/10/12 14:55

0

1

HTMLのページで、コンテンツが短い時だけフッターを一番下に固定したい

ページを作ったときにコンテンツが短いと、フッターの下に空白が空いてしまいます。
それを避けるためにフッターのCSSをposition:fixed;にして、一番下に固定しました。

ところがそうすると、コンテンツが長くなったときにフッターがコンテンツと被ります。

そのためjavascriptでコンテンツの長さに合わせてposition:fixed;を付けたり外したりしよう、と思いました。

で、色々やってみたのですが画面幅をリサイズしたときにうまく行ったりいかなかったりして安定しません。
どこかコードの書き方を間違えているのでしょうか。

どなたかご教授お願いいたします。

該当のソースコード

html

1<!doctype html> 2<html> 3<body> 4<header> 5</header> 6 7 <div style="width:100%;background-color:skyblue;height:auto;">コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ、コンテンツ</div> 8 9 <footer id="footer"> 10 footer 11 </footer> 12 13</body> 14</html> 15

css

1.fixed{ 2 position:fixed; 3 bottom:0; 4}

javascript

1window.addEventListener('load', footerFixed); 2window.addEventListener('resize', footerFixed); 3function footerFixed(){ 4 const targetElement = document.getElementById( "footer" ) ; 5 const ClientRect = targetElement.getBoundingClientRect() ; 6 7 if(window.innerHeight > (ClientRect.top + ClientRect.height)){ 8 targetElement.classList.add('fixed'); 9 }else { 10 targetElement.classList.remove('fixed'); 11 } 12}

補足情報(FW/ツールのバージョンなど)

ここにコードをあげてみました。

https://jsfiddle.net/egt7xqcf/

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

bodymin-height を設定してフッターは position: absolute; で固定すれば javascript なしでいけます。

css

1body { 2 position: relative; 3 min-height: calc(100vh - 50px); 4 margin: 0; 5 padding-bottom: 50px; 6} 7 8footer { 9 position: absolute; 10 bottom: 0; 11 width: 100%; 12 height: 50px; 13 background-color: pink; 14}

質問のJSコードでなぜうまくいかない場合があるのか考察してみました。
まず、フッターに fixed を設定しておいて、下記のコードで動作を確認してみました。

js

1window.addEventListener('load', footerFixed); 2window.addEventListener('resize', footerFixed); 3function footerFixed(){ 4 const targetElement = document.getElementById( "footer" ) ; 5 const ClientRect = targetElement.getBoundingClientRect() ; 6 console.log(window.innerHeight, ClientRect.top + ClientRect.height); 7}

画面サイズを変更するとコンソールに下記のように出力されます。

376 376 377 376.8000183105469 378 377.6000061035156 379 379.20001220703125 ※ 380 380 381 380.8000183105469 382 381.6000061035156 383 383.20001220703125 ※ 384 384

たまに、window.innerHeight より ClientRect.top + ClientRect.height が大きい場合があります。
(※の行)

画面高を変更することで、 ClientRect.top も変化する。相互に変化するものを比較するということは非常に危なっかしい状態であると推測できます。

そこで、画面高を変更しても変化しないものを基準にすればいいのでは、ということで、一つ前の要素の下辺位置にフッターの高さを足したものと比較するコードを書いてみました。

js

1window.addEventListener('load', footerFixed); 2window.addEventListener('resize', footerFixed); 3function footerFixed(){ 4 const targetElement = document.getElementById( "footer" ) ; 5 const ClientRect = targetElement.getBoundingClientRect() ; 6 const previousElementRect = targetElement.previousElementSibling.getBoundingClientRect() ; 7 if(window.innerHeight > (previousElementRect.top + previousElementRect.height + ClientRect.height)){ 8 targetElement.classList.add('fixed'); 9 }else { 10 targetElement.classList.remove('fixed'); 11 } 12}

当方のテストでは安定して動作してます。

投稿2021/10/12 17:44

編集2021/10/13 01:34
hatena19

総合スコア34367

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

donkuri

2021/10/12 23:25

ありがとうございます。 こんなやり方もあるんですね! ただ、javascriptはどこが間違えてたかも知りたいです。
hatena19

2021/10/13 01:32

それについての考察と解決策を回答に追記しましたので、ご参考に。
donkuri

2021/10/13 02:56

おおお!すごい 色々と勉強になります。 内容をしっかり確認させていただきます。 ありがとうございました。
donkuri

2021/10/13 06:10

headerにたくさんテキストを入れてテストしてみたところ、頂いたコードでうまくいきました。 ただよく分からないないのが、 ClientRect.topはダメで、 previousElementRect.topは大丈夫なのがよく分からないです。 どちらも画面高と連動してるはずなのですが。。。 とりあえず頂いたコードで色々考えてみます。 ありがとうございました。
hatena19

2021/10/13 06:23

Fixed で bottom:0; の要素は画面高と連動して、ClientRect.top が変化しますよね。 常に画面最下辺に位置しないとダメなので。 で、この 画面高 と ClientRect.top + ClientRect.height の値が本来は一致するはずなんですが、 コンソールの出力をみると、ClientRect.top + ClientRect.height の値が画面高とは微妙にずれてますよね。 たま、画面高より大きくなることもあります。 なぜ、そうなるかは、私には分かりません。内部的に計算するときの誤差なのか、タイミングの問題なのか、、、、 どちらにしてもこれでは使えません。 previousElement は画面高に対して位置が変化しません。画面高と連動していないです。
donkuri

2021/10/13 08:00

なるほど previousElementも画面高と連動しているかと思いましたが、確かにそうですね。 勉強になりました。 何度もお答えいただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問