这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战
BFC(块级格式化上下文)
- 块格式化上下文是页面上的一个独立的渲染区域,容器里面的子元素不会在布局上影响外面的元素。
- 它是决定块盒子的布局及浮动元素相互影响的一个因素。
css在什么情况会创建一个块格式化上下文
- 根元素,即HTML元素(最大的一个BFC)
- 浮动(float的值不为none)
- 绝对定位元素(position的值为absolute或fixed)
- 行内块(display为inline-block)
- 表格单元(display为table、table-cell等HTML表格相关属性)
- 弹性盒(display为flex或inline-flex)
- 默认值。内容不会被修剪,会呈现在元素框之外(overflow不为visible)
✨BFC的作用
📌1. 让父元素包含子浮动元素,清除内部浮动。(对子元素设置浮动后,父元素会发生高度塌陷,也就是父元素的高度变为0。)
.father {
/* 父级没有设置高度,子元素浮动,产生父元素高度塌陷 */
width: 100px;
background-color: burlywood;
}
.children {
float: left;
width: 50px;
height: 50px;
background-color: coral;
}
<!-- 1. 清除内部浮动 -->
<div class="father">
<div class="children"></div>
</div>
-
父级没有设置高度,子元素浮动,产生父元素高度塌陷
-
解决方法:只需要把父元素变成一个BFC即可,常用的方法是给父元素设置
overflow:hidden
.father { /* 父级没有设置高度,子元素浮动,产生父元素高度塌陷 */ width: 100px; /* 解决高度塌陷,把父元素变成BFC */ overflow: hidden; border: 3px solid burlywood; }
-
设置父元素变成
BFC
后,遵循BFC布局规则第6条: 计算BFC
的高度时,浮动元素也参与计算
📌2. 上下margin重合问题。(分属于不同的BFC时,可以阻止margin重叠)
.father {
width: 100px;
border: 3px solid rgb(83, 141, 230);
}
.children1 {
width: 50px;
height: 50px;
margin-bottom: 10px;
background-color: coral;
}
.children2 {
width: 50px;
height: 50px;
margin-top: 10px;
background-color: coral;
}
<div class="father">
<div class="children1"></div>
<div class="children2"></div>
</div>
-
如图所示:虽然两个子元素都设置了外部的margin,但是只有两元素之间只有10px,并非20px
-
解决方法:给任意一个子元素的外侧包裹一个块级元素,并为这个块级元素设置
overflow:hidden
.box {
overflow: hidden;
}
<div class="father">
<div class="children1"></div>
<div class="box">
<div class="children2"></div>
</div>
</div>
-
遵循BFC布局规则第2条:
Box
垂直方向的距离由margin
决定。属于同一个BFC
的两个相邻Box
的margin
会发生重叠 -
注意:应该避免这样添加margin,尽量在同一个方向给元素添加,例如:都添加顶部margin
📌3. 元素被浮动元素覆盖问题
.aside {
float: left;
width: 100px;
height: 150px;
background-color:coral;
}
.main {
height: 200px;
background-color: rgb(238, 190, 150);
}
<div class="aside"></div>
<div class="main"></div>
-
如图所示:浮动的元素覆盖住了后面的元素
-
为什么会这样?因为
BFC
布局规则第3条规定:每个元素的margin box
的左边,与包含块border box
的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。因此,虽然存在浮动的元素`aside,但main的左边依然会与包含块的左边相接触。 -
解决方法:遵循BFC布局规则第4条:BFC的区域不会与float box重叠。通过触发
main
生成BFC
,来实现。
.main {
/* 将其转换为BFC */
overflow: hidden;
}
-
适用场景: 自适应两(三)栏布局(避免多列布局由于宽度计算四舍五入而自动换行)
-
左图右文
img { float: left; width: 100px; height: 100px; } .box { width: 30px; height: 30px; background-color: cornflowerblue; } p { overflow: hidden; width: 100px; }
<img src="./img/sky.webp" alt="天空"> <div class="box"></div> <p>超长的文字</p><p>超长的文字</p> <p>超长的文字</p><p>超长的文字</p>
-
如图
-
问题:为什么 div 的左上角被覆盖了,而文本却没有被覆盖?因为
div
会被float
覆盖,而文本却没有被float
覆盖,是因为float
当初设计的时候就是为了使文本围绕在浮动对象的周围。
总结
- 其实以上的例子都体现了BFC的第5条布局规则:
BFC
就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。 - BFC布局规则:
- 第1条:内部的Box会在垂直方向,一个接一个地放置。
- 第2条:Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
- 第3条:每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- 第4条:BFC的区域不会与float box重叠。
- 第5条:BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 第6条:计算BFC的高度时,浮动元素也参与计算