CSS 解惑 - 如何让 Footer 始终固定在页面底部

发布于 2023-06-30 19:50:49 字数 3625 浏览 34 评论 0

需求

有这样一个需求:

  • 当页面内容高度小于屏幕高度时,Footer 固定在屏幕底部;
  • 当页面内容高度大于屏幕高度时,Footer 固定在页面底部,即:跟随在内容尾部,滚动条到最底部时看到。

踩过的坑

第 1 种方案:绝对定位 + padding

body{
    position : relative;
    padding-bottom: 60px;
}

footer{
    position : absolute;
    bottom : 0;
    width : 100%;
    height : 60px;
}

这种方案可以保证 footer 一直在屏幕底部,当滚动条滚到最底部时,页面内容也不会被 footer 挡住。

但是问题就是:当在滚动页面的过程中,底部的 Footer 始终会挡住一部分页面的视线。

第 2 种方案:js 控制 footer 的定位

var resizeFooter = function(){
    if(document.body.clientHeight > window.innerHeight){
        document.querySelector('footer').style.position = 'relative';
        return;
    };
    document.querySelector('footer').style.position = 'absolute'
};

//页面加载完成后先计算一下高度,是否出现滚动条。
window.addEventListener('load',function(e){
	resizeFooter();
});

//页面变化之后,重新调整 footer
window.addEventListener('resize',function(e){
	resizeFooter();
});

这种方案看是没有问题,但是实际上却有一个非常大的坑。

假如系统是 SPA 单页面应用,那么页面局部内容发生改变以后,就会影响到 footer 的显示。也就是说,你得考虑所有动态改变页面内容后,都得调用一次 resizeFooter

更加严峻的问题是,假如你使用的是 MVVM 框架,比如:vue,那么你调用 resizeFooter 一定需要在页面数据双向绑定完成之后,也就是页面充分渲染完之后才能调用,也就是 mounted 回调钩子中触发。

如果其他框架没有提供这类回调钩子,你可能就要崩溃了,自己写个 setTimout 延后一段时间执行?更不可靠。

而且这种方式,即便你 JS 控制的再好,也会在页面上看起来,Footer 有个不自然的变化!

完美的解决方案

html {
    position: relative;
    min-height: 100%;
}

body {
    margin-bottom: 60px;
}

footer {
    position: absolute;
    bottom: 0;
    width: 100%;
    height: 60px;
}

只需要以上代码即可,另外需要注意 IE10 下有个 bug,需要 HACK 一下。

/*!
 * IE10 viewport hack for Surface/desktop Windows 8 bug
 * Copyright 2014-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */

// See the Getting Started docs for more information:
// http://getbootstrap.com/getting-started/#support-ie10-width

(function () {
  'use strict';

  if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
    var msViewportStyle = document.createElement('style')
    msViewportStyle.appendChild(
      document.createTextNode(
        '@-ms-viewport{width:auto!important}'
      )
    )
    document.querySelector('head').appendChild(msViewportStyle)
  }

})();

以上内容参考于 Bootstrap 示例: Sticky footer

补充 2019 年 03 月 12 日 19:30:37

有 5 种解决方案,参考: https://css-tricks.com/couple-takes-sticky-footer/

延伸

CSS 布局中有一种 “粘性布局”,即: position:sticky ,跟我们刚才的 footer 控制的需求正好相反。

  • 我们的需求:当内容高度小于屏幕高度时,footer 固定在底部,否则相对内容高度显示;
  • 粘性布局的特性:当内容到达粘性阈值前相对内容显示,达到后固定不变。

所以,粘性布局我们无法使用,但是作为学习,恰好跟我们的这个案例相反,还是值得一看的。

想了解这一特性,可以参考学习 position:sticky 语法以及如何爬坑:

参考

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

罪#恶を代价

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

13886483628

文章 0 评论 0

流年已逝

文章 0 评论 0

℡寂寞咖啡

文章 0 评论 0

笑看君怀她人

文章 0 评论 0

wkeithbarry

文章 0 评论 0

素手挽清风

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文