css中的BFC详解
BFC(Block Formatting Context)块级格式化上下文,是用于布局块级盒子的一块渲染区域。MDN上的解释:BFC是Web页面 CSS 视觉渲染的一部分,用于决定块盒子的布局及浮动相互影响范围的一个区域
# BFC触发方式
- 根元素,即HTML标签
- 浮动元素:float值为left、right
- overflow值不为 visible,为 auto、scroll、hidden
- display值为 inline-block、table-cell、table-caption、table、inline-table、flex、inline-flex、grid、inline-grid
- 定位元素:position值为 absolute、fixed
注意:display:table也可以生成BFC的原因在于Table会默认生成一个匿名的table-cell,是这个匿名的table-cell生成了BFC。
# BFC的特性
- 内部的Box会在垂直方向上一个接一个的放置。
- 垂直方向上的距离由margin决定
- bfc的区域不会与float的元素区域重叠。
- 计算bfc的高度时,浮动元素也参与计算
- bfc就是页面上的一个独立容器,容器里面的子元素不会影响外面元素。
# BFC应用
- 外边距折叠
属于同一个BFC的两个相邻块级子元素的上下margin会发生重叠,(设置writing-mode:tb-rl时,水平margin会发生重叠)。所以当两个相邻块级子元素分属于不同的BFC时可以阻止margin重叠。 这里给任一个相邻块级盒子的外面包一个div,通过改变此div的属性使两个原盒子分属于两个不同的BFC,以此来阻止margin重叠。
下面样式, box1, box2边距会重叠。可以通过在box1上层加一个wrapper包裹,设置overflow: hidden,来实现新的bfc解决边距重叠问题。
<!-- html -->
<div class="container">
<div class="box1"></div>
<div class="box2"></div>
</div>
/* css */
.container {
overflow: hidden;
width: 100px;
height: 100px;
background-color: red;
}
.box1 {
height: 20px;
margin: 10px 0;
background-color: green;
}
.box2 {
height: 20px;
margin: 20px 0;
background-color: green;
}
- 包含浮动块(清除浮动)
通过改变包含浮动子元素的父盒子的属性值,触发BFC,以此来包含子元素的浮动盒子。
<!-- 浮动的元素会脱离普通文档流,来看下下面高度塌陷一个例子: -->
<div style="border: 1px solid #000;">
<div style="width: 100px;height: 100px;background: #eee;float: left;"></div>
</div>
<!-- 一个文字环绕的例子 -->
<div style="height: 100px;width: 100px;float: left;background: lightblue">我是一个左浮动的元素</div>
<div style="width: 200px; height: 200px;background: #eee">
我是一个没有设置浮动, 也没有触发 BFC 元素, width: 200px; height:200px; background: #eee;
</div>
上述两个例子都可以通过设置overflow: hidden 来解决浮动问题
- 不被浮动元素覆盖
以常见的两栏布局为例。左边固定宽度,右边不设宽,因此右边的宽度自适应,随浏览器窗口大小的变化而变化。
<div>
<div class="column0"></div>
<div class="column1"></div>
</div>
.column0 {
float: left;
width: 200px;
height: 300px;
margin-right: 10px;
background-color: red;
}
.column1 {
overflow: hidden; /*创建bfc */
height: 300px;
background-color: purple;
}
还有三栏布局。左右两边固定宽度,中间不设宽,因此中间的宽度自适应,随浏览器的大小变化而变化。
<div class="contain">
<div class="column0"></div>
<div class="column1"></div>
<div class="column2"></div>
</div>
.column0,
.column1 {
float: left;
width: 100px;
height: 300px;
background-color: green;
}
.column1 {
float: right;
}
.column2 {
overflow: hidden; /*创建bfc*/
height: 300px;
background-color: red;
}