4-BFC和高度塌缩

4-BFC和高度塌缩

BFC和高度塌缩

高度塌缩

在浮动布局中,父元素的高度默认是被子元素撑开的

当子元素浮动后,脱离文档流,子元素从文档流中脱离将会无法撑起父元素的高度,导致父元素的高度丢失

父元素高度丢失以后,其下的元素会自动上移,导致页面的布局混乱

子元素(青色)未浮动

子元素浮动后

子元素浮动后,父元素高度塌缩,父元素的兄弟元素上行,占据原来父元素的位置

BFC

BFC(Block Formatting Context)块级格式化环境,为CSS的一个隐藏属性

元素开启 BFC 后的特点:

  • 不会被浮动元素覆盖
  • 父子元素外边距不会重叠
  • 可以包含浮动的元素

打开BFC的方法:

  • 设置为浮动(不推荐):很明显下方元素被覆盖了,总不能让所有元素都浮动吧
  • 设置为行内块元素(不推荐):不再独占一行,宽度变了,同时与下方元素产生了一点空隙
  • 设置overflow为非visible值:既没有覆盖元素,也保持了独占一方的特性(保持了宽度),与下方元素也保持了最初的间隙

clear

如果我们不希望某个元素因为其他元素浮动的影响而改变位置,可以通过

clear属性来清除浮动元素对当前元素所产生的影响

clear作用:清除浮动元素对当前元素所产生的影响(本质是为元素添加一个margin-top属性,值由浏览器自动计算)

子元素和父元素相邻,外边距重合的情况:

未给子元素上边距

给子元素加上上边距后

子元素和父边距相邻且加上上边距后,边距传递到父元素,父元素和子元素一起下行

利用clear来解决高度塌缩

子元素浮动后脱离文档流,父元素高度塌缩,解决方法:

  • 可以增加一个子元素son2,让其撑开父元素的高度
  • son2使用clear清除son1浮动的带来的效果(即浏览器自动为son2加上一个son1高度的外边距)
  • 同时为了避免son2和父元素的外边距相邻,把外边距传递给父元素,son2应该在son1之后

父元素高度塌缩后,其兄弟元素(红色)上行

添加子元素son2后修复父元素塌缩

网页设计:结构(HTML)+表现(CSS)+行为(JS),上面使用HTML种son2完成了表现,为了更贴合网页设计概念,取消使用son2,利用CSS中伪元素::after

使用::after达成同样的效果

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
  <style>
.father {
/* 父元素没有指定宽高 */
background-color: aquamarine;
}

.son1 {
width: 50px;
height: 50px;
background-color: rgb(37, 177, 177);
float: left;
}

/* 添加子元素 */
.father::after {
/* .father::after默认是行内元素,不是独占一行,转为块元素 */
display: block;
/* 添加内容为空 */
content: '';
/* 清除浮动影响 */
clear: both;
}

.box {
width: 55px;
height: 55px;
background-color: rgb(207, 11, 11);
}
</style>

<body>
<div class="father">
<div class="son1"></div>
</div>
<div class="box"></div>

clearfix

使用clearfix同时解决父元素高度塌缩和子元素父元素外边距重合:

1
2
3
4
5
6
.clearfix::before,
.clearfix::after {
content: "";
display: table;
clear: both;
}

解决子元素父元素外边距重合:

1
2
3
4
.clearfix::before{
content: "";
display: table;
}

解决父元素塌缩:

1
2
3
4
5
.clearfix::after {
content: "";
display: table;
clear: both;
}

使用display: table是因为block有默认高度会影响布局,table没有默认高度

1
2
3
4
5
6
<div class="father">
<!-- ::before在这解决将子元素son1和father隔开,上边距不相邻后解决子元素父元素外边距重合 -->
<div class="son1"></div>
<!-- ::after在这里解决父元素塌缩,不能是::before解决,因为.father::before会和父元素发生上边距重合 -->
</div>
<div class="box"></div>