Sticky Footer 实现

date
Jan 3, 2017
slug
css-sticky-footer
status
Published
tags
HTML&CSS
summary
底部固定的使用场景以及具体实现
type
Post

问题的由来

notion image
在开发中碰到了如左图这样的场景:
登陆图标被滚动条遮挡住了,需求是滚动条出现在头部的下方。实现很简单,在头部(header)和内容(section)外面再包裹一层(.wrapper),给 .wrapper 层高度 100%;然后让内层 section 绝对定位,设置 top/overflow-y 即可。
HTML 结构如下:
<div class="wrapper">
   <header>
    <span class="title">This is header!</span>
	  </header>
	  <section>
    这里添加超过页面高度的内容
    </section>
</div>
样式代码如下:
body {
  overflow: hidden;
}

.wrapper {
	position: relative;
	height: 100%;
  min-height: 100%;
	overflow: hidden;
}

header {
  position: relative;
  padding: 0 90px;
  height: 48px;
  background: #efeff0;
  border-bottom: 1px solid #fff;
  text-align: center;
}

section {
  position: absolute;
	top: 48px;
	left: 0;
	bottom: 0;
	right: 0;
	overflow-y: scroll;
}
 
但是这样显示section中的内容是显示不出来的。如下:
notion image
这里的原因是因为我们在 .wrapper 中设置 height: 100% 而设置高度百分比时这个百分比时根据父元素的高度来计算的,这里的父元素是 body&html,没有设置 height 时父元素 body&html 的 height: auto 这时要求浏览器根据这样一个缺省值来计算百分比高度时,只能得到 undefined 的结果。也就是一个 null 值,浏览器不会对这个值有任何的反应(详情见下面链接)。所以我们新增如下样式:
html,body {
 height: 100%;
}
body {
  overflow: hidden;
}
效果如下:
notion image
如果此时往底部加一个返回顶部按钮会怎么样?

Sticky Footer 具体实现

底部固定又叫 css sticky footer,网上的实现方式有很多。下来介绍一个简单实用的方式。
HTML 结构如下:
<div class="content-wrapper">
    <header>
    	<span class="title">This is header!</span>
    </header>
    <div class="content"></div>
    <div class="close">
        ×
    </div>
</div>
CSS 结构如下:
html,body {
	height: 100%;
}

.content-wrapper {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	min-height: 100%;
	overflow: auto;
	background: rgba(7, 17, 27, .8);
	z-index: 100;
}

header {
	position: relative;
	width: 100%;
	height: 48px;
	background: #efeff0;
	text-align: center;
}

.content {
	width: 90%;
	margin: 0 auto;
	padding-bottom: 64px;
}
        
.close {
	position: relative;
	width: 100%;
	height: 64px;
	margin: -64px auto 0;
	padding-top: 16px;
	font-size: 32px;
	clear: both;
	text-align: center;
}
效果如下:
notion image
我们的关闭 icon 均在文字的最下方,根据内容的高度变化而改变。显然这并不是我们想要的效果,我们想要的是不论内容是否撑满屏幕高度这个关闭的 icon 都要固定在最下方,而上图出现在内容的底部而不是屏幕的底部。所以我们应该对为这个整体再包裹一层,然后把 .close 这个 div 放出去与 content-wrapper 同级即可。修改后的 HTML/CSS 代码如下:
<div class="wrapper">
    <div class="content-wrapper">
        <header>
        	<span class="title">This is header!</span>
        </header>
        <div class="content">
        </div>
    </div>
    <div class="close">
            ×
    </div>
</div>
html,body {
	height: 100%;
}

.wrapper {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: rgba(7, 17, 27, .8);
	z-index: 100;
}

.content-wrapper {
	width: 100%;
	min-height: 100%;
}

header {
	position: relative;
	width: 100%;
	height: 48px;
	background: #efeff0;
	text-align: center;
}

.content {
	width: 90%;
	margin: 0 auto;
	padding-bottom: 64px;
}
        
.close {
	position: relative;
	width: 100%;
	height: 64px;
	margin: -64px auto 0;
	padding-top: 16px;
	font-size: 32px;
	clear: both;
	text-align: center;
}
最终效果如下:
notion image

Sticky Footer 实现总结

最后我们来总结一下 css sticky footer 的步骤。
  1. 需要一个大容器(.content-wrapper)设置 min-height 为100%,撑满整个可视区域,不然你需要 sticky 的 footer 就不会出现在你的视线里
  1. 在 content-wrapper 中创建你的内容区域,在内容区内建立了一个 content ,这时的内容区域(content)一定要设置 padding-bottom 来为你的 footer(.close) 占位
  1. 在 content-wrapper 同级下创建你的 footer(.close),然后相对定位(相对于content-wrapper)然后这里的 margin-top 必须为负(填充你在第二步中所占的空间这里的负值必须与第二步中设置的值相同,锁死 footer 的位置)。

© i7eo 2017 - 2022