夏天快到了,又到了白大腿横飞的时代。坐下来摸了摸腰间残留的今年五花肉就突然觉得时光待我并不怎么宽厚啊。
昨天写了一篇关于 浮动 的文章,里面就提到了BFC 并介绍了几种利用BFC来清除浮动的方式,那么今天来解答一下: 到底什么是BFC?
一、 什么是BFC?
其实你叫我单纯的回答你们什么是 BFC ,我只能告诉你BFC的全称(Block Fromatting Context)和中文翻译名(块级格式化上下文)。如果你叫我深入的解释这这个名词,这就好比你叫我来解释什么叫男生/女生一样,大家我都知道这两个名词,但是你叫人跟你解释清楚却是很麻烦,同样bfc也是如此。
1.1、 w3c对BFC的解释
首先我们来看看W3C对BFC的解释
浮动元素、绝对定位元素等非快级盒子的快级容器(例如:inline-blocks, table-cells, 和 table-captions),以及overflow属性不为visiable的块级元素元素,都会其内容建立新的块级格式化上下文。
在BFC(块级格式化上下文)中,盒在垂直方向一个一个的放置,从包含块的顶部开始,相邻的兄弟盒子之间的垂直距离由margin属性来决定,在同一个BFC(块级格式化上下文)中的相邻兄弟之间的margin会被合并。
在一个BFC(块级格式化上下文)中,最左边的左边距和包含块的左边相同(对于从右向左格式的结构,内外也是挨着的)。即使存在浮动情况(尽管盒子的大小可能因为内部子盒子的浮动而变窄),这也成立,除非子盒子内建立了一个新的BFC(块级格式化上下文),这种情况下,该盒自身可能因为浮动变窄。
讲道理,不知道是不是我翻译的缘故,我硬是没看懂orz! 算了我们还是来看一下中文版MDN对BFC的解释吧:
1.2、 w3c对BFC的解释
块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
下列方式会创建块格式化上下文:
- 根元素或包含根元素的元素
- 浮动元素(元素的 float 不是 none)
- 绝对定位元素(元素的 position 为 absolute 或 fixed)
- 行内块元素(元素的 display 为 inline-block)
- 表格单元格(元素的 display为 table-cell,HTML表格单元格默认为该值)
- 表格标题(元素的 display 为 table-caption,HTML表格标题默认为该值)
- 匿名表格单元格元素(元素的 display为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table)
- overflow 值不为 visible 的块元素
- display 值为 flow-root 的元素
- contain 值为 layout、content或 strict 的元素
- 弹性元素(display为 flex 或 inline-flex元素的直接子元素)
- 网格元素(display为 grid 或 inline-grid 元素的直接子元素)
- 多列容器(元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1)
- column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。 块格式化上下文包含创建它的元素内部的所有内容.
块格式化上下文对浮动定位(参见 float)与清除浮动(参见 clear)都很重要。浮动定位和清除浮动时只会应用于同一个BFC内的元素。浮动不会影响其它BFC中元素的布局,而清除浮动只能清除同一BFC中在它前面的元素的浮动。外边距折叠(Margin collapsing)也只会发生在属于同一BFC的块级元素之间。
二、用代码来解释上面懵懂的话语吧
其实上面找了这么多文档,其实大抵还是不怎么懂的,但是我们就来按照他们的说法来写点点代码,来看下面一段代码:
// html
<div class="parent">
<div class="son"></div>
</div>
// css
*{
margin: 0;
padding: 0;
}
.parent {
width: 200px;
border: 10px solid pink;
margin:100px;
}
.son {
width: 100px;
height: 100px;
background: red;
float: left;
}
复制代码
效果如下:
.parent {
width: 200px;
border: 10px solid pink;
margin:100px;
/*overflow: hidden;*/
/*display: inline-block;*/
/*display: flex;*/
/*display: flow-root;*/
/*position: absolute;*/
...
}
复制代码
这里我们发现了一个情况:即使是子元素添加了浮动属性,父元素都会被子元素撑开。这里我们就差不多能明白前面W3C的第一段话,使用上面一系列的属性能让父盒子产生BFC,我在这里总结一下BFC的功能,就是让父盒子包裹起子盒子来,也就可以达到 清除浮动 的功能。
然后我们在代码的基础上增加一个儿子来继续探究BFC的作用:
// html
<div class="parent">
<div class="son"></div>
<div class="son1"></div>
</div>
// css
.son {
width: 100px;
height: 100px;
background: red;
float: left;
}
.son1 {
width: 100px;
height: 100px;
background: blue;
display: flow-root;
}
复制代码
首先在son1中不添加display属性的时候效果如下:
这里有这么个东西值得大家注意的,如果我在son1盒子上面增加一个margin-left的属性,我们发现并没有效果,直到margin-left的长度大于son盒子的时候才会产生偏移。