每次谈到块格式化上下文(简称 BFC),脑袋里总是感觉懵懵的,今天写一篇博客,梳理一下知识点。
块格式化上下文,说复杂也复杂,总给人一种神妙的感觉,但是就在应用的层面上来说,牢牢记住几个关键点,清楚 BFC 大概是什么、怎么创建一个 BFC、BFC 有什么特点、BFC 有什么作用,其实也就没什么复杂的了。
BFC 是啥
先看一下官方的文档解释:
块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
每句话都通俗地理解一下,在 web 页面中,BFC 就是渲染可以看见的 css 内容的一部分,是一个能够让块盒子布局的区域,在该区域中也能让浮动元素与其他元素进行交互。其实在我们不知道 BFC 的时候,我们难道不就是在渲染 css、做块盒子布局、必要的时候让元素浮动吗?是的,那是因为我们本来就在一个 BFC 中进行布局,在下文的 BFC 创建条件中,就可以看到根元素就会创建一个 BFC 。
BFC 创建条件
以下是 BFC 的创建条件:
- 根元素(也就是
<html>标签) - overflow 不为 visible 的元素
- positon 为 absolute 或 fixed 的元素
- float 不为 none 的元素(浮动元素)
- display 为以下值的元素:① flow-root。 ② inline-block(行内块元素)。 ③ flex 或 inline-flex 元素的直接子元素。 ④ grid 或 inline-grid 元素的直接子元素。 ⑤ table-cell(表格单元格) ⑥ table-caption(表格标题) ⑦ table、table-row、table-row-group、table-header-group、table-footer-group、inline-table。
- contain 值为 content、layout、paint(contain 值不为none、strict、size、style)
- column-span 值为 all 的元素,即使该元素没有包裹在一个多列容器中。
- 多列容器,column-count 或 column-width 不为 auto 的元素。
BFC 中的元素有哪些特点
第一个特点是 BFC 元素特性的表现原则就是,内部子元素再怎么翻江倒海,翻云覆雨都不会影响外部的元素。
第二个特点是 BFC 中的盒子对齐:在 BFC 中,每个盒子的左外边框紧挨着包含块的左边框(从右到左的格式,则为紧挨右边框)。即使存在浮动也是这样的(尽管一个盒子的边框会由于浮动而收缩),除非这个盒子的内部创建了一个新的BFC浮动,盒子本身将会变得更窄。
可以用 BFC 做什么
1.防止因浮动导致高度塌陷
高度塌陷是指当为一个元素设置为浮动后,那么该元素就会脱离常规流,对于其他处于常规流的元素来说就好像该浮动的元素不存在一样,所以该浮动元素的父元素的高度就不会包含该浮动元素,若父元素中除了此浮动元素外没有其他内容,那么这个父元素的高度就会显示为0,这就是高度塌陷问题。
//html:
<div class="outer">
<div class="inner"></div>
</div>
//css:
.outer{
border:1px solid red;
}
.inner{
width:100px;
height:100px;
background:green;
float:left;
}
结果:
怎么解决高度塌陷问题呢?也就是怎么让浮动元素的父元素的高度能够包含浮动元素,可以用清除浮动的那些办法,在这里我们利用 BFC 来解决,那就是让这个父元素创建一个 BFC ,可以给这个父元素设置上述 BFC 的创建条件中的任何一个属性,当父元素创建了一个 BFC 之后,其高度就能够包含浮动元素了。
2.防止外边距折叠
在常规文档流中,盒子都是从包含块的顶部开始一个接着一个垂直堆放,如果两个兄弟盒子在同一个 BFC 中,那么他们之间的垂直距离则是由他们单个个体的外边距所决定的,而不是他们的两个外边距之和,若外边距的值不相同,则按照值大的为准。若要防止外边距折叠,则需要将其中的一个兄弟元素包含在一个新的 BFC 里面,这样他们就属于不同的 BFC 中了,该元素也就不会和其兄弟元素之间存在外边距折叠问题了。见代码:
//html:
<div class="outer">
<div class="div1"></div>
<div class="div2"></div>
<div class="newBfc">
<div class="div3"></div>
</div>
</div>
//css:
.outer{
border:1px solid red;
overflow:hidden;
}
.div1 {
width: 30px;
height: 30px;
background: red;
margin: 10px 0;
}
.div2 {
width: 30px;
height: 30px;
background: green;
margin: 10px 0;
}
.div3 {
width: 30px;
height: 30px;
background: black;
margin: 10px 0;
}
.newBfc{
display:flow-root; //创建一个 BFC
}
结果:
3.解决文字环绕问题
参考文章:理解CSS中BFC
4.多列布局最后一个元素溢出问题
参考文章:理解CSS中BFC
本文参考:
CSS深入理解流体特性和BFC特性下多栏自适应布局--张鑫旭
本文只是简要介绍了一下 BFC,更多内容欢迎留言讨论。