理解 BFC
BFC(Block Formatting Context, 块格式化上下文),根据 MDN 的解释,它是布局过程中生成块级盒子的区域,也是浮动元素与其他元素的交互限定区域。看这个定义是真的很让人摸不着头脑,简单来说, BFC 就是页面中的一个独立容器,一个页面可以有很多的这样的容器,容器里的子元素与外界互不干扰。先看以下例子,你或许就能知道 BFC 到底是何方神圣了:
例一、现有一个
div.parent
包裹着它的儿子div.child
:1
2
3<div class="parent">
<div class="child"></div>
</div>1
2
3
4
5
6
7
8.parent {
outline: 1px solid red;
}
.child {
width: 150px;
height: 150px;
background-color: #ccc;
}此时
div.parent
的高度即为其儿子div.child
的高度150px
。如果为div.child
添加左浮动,那么div.parent
就无法包住它的儿子div.child
,其高度变为0
(如下图所示)。
但是,如果为
div.parent
创建一个 BFC ,就可以使它包住其儿子。如:1
2
3
4
5
6
7
8
9
10.parent {
outline: 1px solid red;
display: flow-root;
}
.child {
float: left;
width: 150px;
height: 150px;
background-color: #ccc;
}例二、现有两个兄弟
div.left
和div.right
,我为div.left
添加左浮动,使得他们能够并排排列:1
2<div class="left">div.left</div>
<div class="right">div.right</div>1
2
3
4.right {
height: 150px;
outline: 1px solid red;
}结果发现,即使
div.left
设置了右边距,这两兄弟还是重叠在了一起,如下图所示:
若想将两者分离开来,我们可以为
div.right
创建一个 BFC ,即:1
2
3
4
5.right {
height: 150px;
outline: 1px solid red;
display: flow-root;
}
通过以上两个例子,我们初步了解了 BFC 可以解决浮动元素对布局的影响,如浮动元素的父元素无法包住自身的问题、浮动元素与其他兄弟元素重叠的问题。此外,它还可以阻止 margin collapse(坍塌?不知道该如何翻译..看例子吧)的问题。例如:
1 | <div class="outer"> |
1 | div.outer { |
我们可以看到,在 p
元素和其父元素 div.outer
的边缘之间没有任何东西的情况下, div.outer
像是塌了一样顶部直接了第一个 p
元素的顶部齐平,同理底部。
如果我们为 div.outer
创建 BFC ,那么就可以解决这个问题:
1 | div.outer { |
细心的同学可以发现,尽管 div.outer
被撑起来了,但相邻的两个 p
元素还是发生了 margin 的重叠。这就是 BFC 的布局规则之一:同一 BFC 内的两个相邻块元素上下 margin 会重合。若想解决这个问题,只需在其中一个 p
元素外创建一个 BFC 包裹器即可:
1 | <div class="outer"> |
1 | div.outer { |
创建 BFC 的方法
在上面的所有例子中,我都使用 display: flow-root;
来创建 BFC ,当然还有其他的方法,例如:
- 根元素
float
属性不为none
overflow
属性不为visible
的块元素position: absolute;
或position: fixed;
display: flex;
或display: inline-flex;
display: grid;
或display: inline-grid;
display: inline-block;
,display: table-cell;
或display: table-caption;
column-span: all;
- … view more on MDN
这些大法虽好,但很容易产生副作用。例如,如果我们使用 overflow: auto;
来创建一个 BFC ,在某些情况下,你可能会发现有一个多余显示的滚动条或者像我们上述例子中的 outline
会被剪切掉。而 flow-root 是 CSS2 中专门设计为创建 BFC 的属性,它不会产生多余的副作用,所以建议使用这个属性来代替其他方法。
不使用 BFC 清除浮动(题外扩展)
若要清除浮动,我们可以使用 clearfix hack ,只需将 clearfix
加到浮动元素的父元素的 class
属性中即可,而不一定非得创建 BFC 来达到清除浮动的效果。例如例一可以通过以下方式达到同样的效果:
1 | <div class="parent clearfix"> |
1 | .parent { |
本文完。
若文中有错误还请指正与包涵!
原文链接:https://caijialinxx.github.io/2018/10/15/block-formatting-context/
转载请注明出处。
参考资料: