一.什么是高度塌陷
高度塌陷是CSS中不给父元素设置高度的时候,如果子元素中有浮动元素,那么父元素在计算高度的时候就不会将浮动元素计算在内,从而造成高度塌陷的一种现象。
看下面的例子
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style>
.father{width: 100%;background-color: darkorange;}
.box1{width: 150px;height: 100px;background-color: pink;float: left;}
.box2{width: 100px;height: 150px;background-color:lavender;float: left;}
</style>
</head>
<body>
<div class="father">
<div class="box1">150 * 100</div>
<div class="box2">100 * 150</div>
</div>
</body>
</html>
给里面两个子元素box设置float:left后,在计算父元素的高度时不会将它们计算在内,所以父元素的高度就为0了,这就是高度塌陷。
二.高度塌陷的解决方法
1.方案一
给父元素设置固定高度,这种方法其实没什么用,在实际开发中大部分情况都是需要高度自适应的,给父元素固定高度违背了高度自适应的原则,不够灵活,不推荐使用。
2.方案二
BFC布局规则:
1.内部的Box会在垂直方向,一个接一个地放置。
2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
3.每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
4. BFC的区域不会与float box重叠。
5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
6. 计算BFC的高度时,浮动元素也参与计算
正是利用BFC的规则6,我们让父元素触发BFC的布局规则就可以解决高度塌陷了,那么如何触发BFC规则呢?
根元素(html)
float属性不为none
position为absolute或fixed
display为inline-block, table-cell, table-caption, flex, inline-flex
overflow不为visible
从上我们可以看到,像HTML整个页面其实也是一个BFC,浮动元素这个整体也是BFC,等等…BFC是一个个独立的系统,内部的任何布局不会影响外部的布局,同样的外部布局也不会影响内部布局。
只要给一个块元素设置上面那些属性就可以出发BFC的布局规则。
通常情况下我们会利用overflow: hidden来触发BFC规则。
给父元素添加属性 overflow: hidden;
优点:浏览器支持好,简单;
缺点:当子元素有定位属性时,设置 overflow: hidden; 容器以外的部分会被裁剪掉。
这种方法的原理是利用了BFC的布局规则,BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。
3.方案三
在子元素的末尾添加一个空的 div ,并设置下方样式
div{
clear: both;
height: 0;
overflow: hidden;
}
优点:所有浏览器都支持,并且容器溢出不会被裁剪;
缺点:在页面中添加无意义的div,容易造成代码冗余。
这种方法很好理解,clear就是清楚浮动的影响的意思,清除左浮动影响clear:left,清除右浮动影响就clear:right,都清除就clear:both。但是这种方法的确定是要给所有不想受到浮动元素影响的元素都加上clear:both很麻烦。
上面给第三个div加上clear:both效果如下:
.box3{width: 300px;height: 200px; background-color: skyblue;clear:both;}
4.方案四
父级元素设置after伪类clear:both
原理还是利用clear:both清除,上面给浮动元素后面的所有元素都写上clear:both很繁杂,我们可以给浮动元素的父级封装成一个清除浮动的类,这个类的作用加上一段空白内容,然后给这一块内容设置clear:both,并且要把它转化成块级元素就OK了。在父级元素后面添加内容我们可以用after伪类。
.clearfix:after {
content: "";
clear: both;
display: block;
}
上面样式可以先写在全局全局样式文件里,通过封装成类名的方法大大简化了我们的代码,只要在浮动元素的父级的类名上加上class="clear.fix"就可以了。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style>
.clearfix:after {
content: "";
clear: both;
display: block;
}
.box1{width: 150px;height: 100px;background-color: pink;float: left;}
.box2{width: 100px;height: 150px;background-color:lavender;float: left;}
.box3{width: 300px;height: 200px;background-color: skyblue;clear: both;}
</style>
</head>
<body>
<div class="father clearfix">
<div class="box1">150 * 100</div>
<div class="box2">100 * 150</div>
</div>
<div class="box3">300 * 200</div>
</body>
</html>