绝对定位的元素会脱离文档流,它们是相对于包含块(通常是最近的具有相对定位、绝对定位或固定定位属性的父元素)进行定位的。当你把一个绝对定位的元素的高度设置为100%时,它会相对于其包含块的高度来确定自己的高度。如果包含块是整个屏幕,那么这个绝对定位的元素设置为100%高度就会占满整个屏幕。
相反,float属性用于让元素浮动在其父元素内部,但是它不会使父元素的高度被撑开,因此,一个使用float的元素设置高度为100%并不会让它占满整个屏幕,因为float的元素仍然存在于父元素的文档流中,而并不会脱离文档流。
因此,通过绝对定位的元素设置高度为100%,可以让这个元素占满整个屏幕,而使用float的元素设置高度为100%则不能实现同样的效果,因为float元素并没有脱离文档流。
方法一、绝对定位(absolute + margin)
给左右两边的元素设置absolute,这样左右两边的元素脱离标准文档流的控制,中间的元素自然会上来,然后给中间的元素设置margin留出左右两边元素的位置。左右两边的元素放在前面可以不计较位置,但中间的元素必须放在最后,否则中间元素的margin设置会把左右两边元素顶到下面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 这里样式的初始化也很重要,不然有空隙 */
* {
margin: 0;
padding: 0;
}
body {
/* 为了使得中间的 div 能够自适应屏幕100%的高度,要这样设置 */
height: 100vh;
}
.left,
.right {
/* 绝对定位的左右 div 是直接放在 body 元素中的,而 body 的高度会自动扩展以适应内容的高度,
也可以通过设置 height: 100vh 让其填满整个视口高度(但只涉及左右div的时候没有必要),
因为脱离了文档流,高度被设置为 100% 时,其定位的参考对象是 body 或者视口,所有可以占满整个屏幕。*/
width: 200px;
height: 100%;
position: absolute;
}
.left {
background-color: green;
left: 0;
}
.right {
background-color: blue;
right: 0;
}
.center {
/* 中间的 div 还在正常文档流布局中,没有脱离文档流,它现在的父元素是body,要是body没有
设置显性高度值的话,那它的高度设置为 100% 是无效的。 */
height: 100%;
margin: 0 200px;
background-color: red;
}
</style>
</head>
<body>
<div class="left">left</div>
<div class="right">right</div>
<div class="center">center</div>
</body>
</html>
注:随着浏览器窗口缩小,会发生压缩,左右元素重叠
方法二、自身浮动(float)
给左右元素分别设置左浮动和右浮动,之后给中间的元素设置margin,设置方法同方法一,三个div的顺序也和方法一的一样。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
height: 100vh;
}
.left,
.right {
width: 200px;
height: 100%;
}
.left {
background-color: green;
float: left;
}
.right {
background-color: blue;
float: right;
}
.center {
height: 100%;
margin: 0 200px;
background-color: red;
}
</style>
</head>
<body>
<div class="left">left</div>
<div class="right">right</div>
<div class="center">center</div>
</body>
</html>
注:随着浏览器窗口缩小,右边元素会被挤到下一行
方法三、圣杯布局(BFC+负margin)
使用margin负值法,使用圣杯布局首先需要将中间元素用div包住,设置float使其形成一个BFC,并且要设置宽度,整个宽度和左边元素的margin负值要相互配合,也就是margin-left = "-中间元素外层div宽度" ,右边元素的margin负值要和它自己的宽度配合,也就是margin-left = “-右边元素宽度”。什么圣杯布局,就是拿中间元素当底,左右元素调整位置打配合。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
/* 这里依旧发挥着重要的作用 */
height: 100vh;
}
.wrap {
width: 100%;
/* 这里的100%高度影响着center的高度 */
height: 100%;
float: left;
}
.left,
.right {
width: 200px;
height: 100%;
}
.left {
background-color: green;
float: left;
margin-left: -100%;
}
.right {
background-color: blue;
float: left;
margin-left: -200px;
}
.center {
height: 100%;
background-color: red;
}
</style>
</head>
<body>
<div class="wrap">
<div class="center">center</div>
</div>
<div class="left">left</div>
<div class="right">right</div>
</body>
</html>
注:随着浏览器窗口缩小,会发生压缩,左右元素重叠,继续缩小之后右边元素会又会被挤到下一行,但是同方法二有不同。
方法四、 flex布局
将左中右三个元素用div包裹起来,给外层div设置display:flex,之后给中间元素设置flex:1,三个元素的顺序是固定的,中间元素要放在中间,不能兼容IE8及以下浏览器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
/* 灵魂酱汁 */
height: 100vh;
}
.wrap {
width: 100%;
height: 100%;
display: flex;
}
.left,
.right {
width: 200px;
height: 100%;
}
.left {
background-color: green;
}
.right {
background-color: blue;
}
.center {
/* 灵魂酱汁 */
flex: 1;
height: 100%;
background-color: red;
}
</style>
</head>
<body>
<div class="wrap">
<div class="left">left</div>
<div class="center">center</div>
<div class="right">right</div>
</div>
</body>
</html>
注:随着浏览器窗口的缩小,会发生压缩,但是不会重叠和换行