有这样一个需求:
body{
position : relative;
padding-bottom: 60px;
}
footer{
position : absolute;
bottom : 0;
width : 100%;
height : 60px;
}
这种方案可以保证 footer 一直在屏幕底部,当滚动条滚到最底部时,页面内容也不会被 footer 挡住。
但是问题就是:当在滚动页面的过程中,底部的 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(link:https://getbootstrap.com/docs/3.3/examples/sticky-footer/)
有 5 种解决方案,参考: https://css-tricks.com/couple-takes-sticky-footer/
CSS 布局中有一种 “粘性布局”,即: position:sticky ,跟我们刚才的 footer 控制的需求正好相反。
所以,粘性布局我们无法使用,但是作为学习,恰好跟我们的这个案例相反,还是值得一看的。

