1. 问题描述
将footer保持在视觉窗口的底部是常见的需求。当页面的内容主体高度较大(超出屏幕可视区域的高度)时,footer元素直接跟在内容后面即可。但是,当一个 HTML 页面包含少量的内容时,footer元素就会坐落在页面的中间,在下面留下空白,这看起来很糟糕,尤其是在大屏幕上。
如下图:
2. 解决方案
我们先给出基础的页面代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>footer</title>
<style>
* {
box-sizing: border-box;
text-align: center;
margin: 0;
padding: 0;
}
header, footer {
color: #FFF;
padding: 20px;
}
header {
background-color: #7BE0AD;
}
main {
padding: 20px;
border: 2px dashed red;
}
footer {
background-color: #457B9D;
}
</style>
</head>
<body>
<div id="container">
<header>
<h1>我是header</h1>
</header>
<main>
<p>我是内容(内容不是很长)</p>
</main>
<footer>
<p>我是footer ©码飞_CC</p>
</footer>
</div>
</body>
</html>
显示效果如下:
2.1 使用position属性实现(兼容较老的浏览器)
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>footer</title>
<style>
* {
box-sizing: border-box;
text-align: center;
margin: 0;
padding: 0;
}
html, body {
height: 100%; /* 1. 需要将页面的高度设置成浏览器可视区域的高度 */
}
#container {
min-height: 100%; /* 2. 需要将容器的高度设置成100% */
position: relative; /* 3. 容器的position设置为relative,给子元素定位提供基点 */
}
header, footer {
color: #FFF;
padding: 20px;
}
header {
background-color: #7BE0AD;
}
main {
padding: 20px;
border: 2px dashed red;
}
footer {
position: absolute;
bottom: 0; /* 4. 设置页脚position为absolute之后,再将其bottom值设为0,即可使其处于页面的底部 */
width: 100%;
background-color: #457B9D;
}
</style>
</head>
<body>
<div id="container">
<header>
<h1>我是header</h1>
</header>
<main>
<p>我是内容(内容不是很长)</p>
</main>
<footer>
<p>我是footer ©码飞_CC</p>
</footer>
</div>
</body>
</html>
显示的效果如下:
几个注意点:
HTML
和body
标记必须设置为height: 100% ;
,这保证我们后面能够设置容器 div
的百分比高度。容器 div
具有一个min-height: 100% ;
,这将确保它在几乎没有任何内容的情况下,也可以保持屏幕的完整高度。容器 div
也被设置为position: relative;
,这使我们能够绝对定位其子元素。- 页脚容器设置为绝对定位,并且
bottom:0;
。宽度设置为100%,width: 100%;
这样页脚才能撑开为可视区域的宽度。 - 这里有个小问题,就是当窗口缩得特别小的时候,
footer元素
会在容器div
上,使得内容被覆盖了。解决方法是设置容器div
的padding-bottom
或border-bottom
的值为footer元素
的高度(这里使用margin-bottom
是没有效果的)。
2.2 使用Flex实现
CSS代码:
* {
box-sizing: border-box;
text-align: center;
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
#container {
min-height: 100%;
display: flex; /* 容器为flex布局 */
flex-direction: column; /* 方向为纵向,保持正常的从上到下文档流 */
}
header, footer {
color: #FFF;
padding: 20px;
}
header {
background-color: #7BE0AD;
}
main {
padding: 20px;
border: 2px dashed red;
}
footer {
margin-top: auto; /* 设置footer的上外边距为auto */
background-color: #457B9D;
}
效果跟使用position的方法一样,但是更加简洁完美,没有position小节中几个注意点
部分的第4条的那个问题。
2.3 使用Grid实现
* {
box-sizing: border-box;
text-align: center;
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
#container {
min-height: 100%;
display: grid; /* 容器为grid布局 */
grid-template-rows: auto 1fr auto;
}
header, footer {
color: #FFF;
padding: 20px;
}
header {
background-color: #7BE0AD;
}
main {
padding: 20px;
border: 2px dashed red;
}
footer {
background-color: #457B9D;
}
效果如下:
使用grid
实现需要注意兼容性问题,从效果图可以看到,它的实现方式是用特殊的网格单元 fr
,使main元素
撑满剩余空间来实现的。
参考内容: