底部固定(sticky footer)

| 字数 1117

  滚动条的出现总是在浏览器的最右边和最下方,牢牢的 fixed在页面上。大多数时候我们看到的是这样的

  

这样子很明显登录的小人按钮被挡住了,而且真的不太美观。这时我们就希望头部吸顶,滚动条出现在下方的div内。如下图:

其实实现很简单,在头部(header)和内容(section)外面再包裹一层(.wrapper),给 .wrapper 层高度 100%;然后让内层 section 绝对定位,设置 top/overflow-y 即可。HTML 结构如下:

1
2
3
4
5
6
7
8
<div class="wrapper">
  <header>
    <span class="title">This is header!</span>
</header>
<section>
    这里添加超过页面高度的内容
</section>
</div>

样式代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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中的内容是显示不出来的。如下:

这里的原因是因为我们在 .wrapper 中设置 height: 100%,而设置高度百分比时这个百分比时根据父元素的高度来计算的,这里的父元素是 body&html,没有设置 height 时父元素 body&html 的 height: auto,这时要求浏览器根据这样一个缺省值来计算百分比高度时,只能得到 undefined 的结果。也就是一个 null 值,浏览器不会对这个值有任何的反应(详情见下面链接)。所以我们需要在将样式修改为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
html,body {
  height: 100%;
  }
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;
}

效果如下:

  底部固定又叫 css sticky footer,网上的实现方式有很多。下来介绍一个简单实用的方式,对应的 HTML 结构如下:
  

1
2
3
4
5
6
7
8
9
<div class="content-wrapper">
<header>
<span class="title">This is header!</span>
</header>
<div class="content"></div>
<div class="close">
×
</div>
</div>

CSS 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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;
}

效果如下:

我们的关闭 icon 均在文字的最下方,根据内容的高度变化而改变。显然这并不是我们想要的效果,我们想要的是不论内容是否撑满屏幕高度这个关闭的 icon 都要固定在最下方,而 exhibition-1.png 中的现象是出现在了内容的底部而不是屏幕的底部。所以我们应该对为这个整体再包裹一层,然后把 .close 这个 div 放出去与 content-wrapper 同级即可。修改后的 HTML/CSS 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
<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>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
.wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
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;
}

最终效果如下:

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