块级格式化上下文(Block Formatting Context)是网页CSS视觉渲染的一部分,并用于决定块盒子的布局。在定位体系(Positioning Scheme)中它属于常规流(Normal Flow)。根据W3C所言:
浮动、绝对定位元素(
position
为absolute
或fixed
)、行内块元素display:inline-block
、表格单元格display:table-cell
、表格标题display:table-caption
以及overflow
属性值不为visible
的元素(除了该值被传播到视点viewport
的情况)将创建一个新的块级格式化上下文。
上面的引言差不多总结了一个BFC是如何形成的。但让咱们用另外一种更通俗易懂的方式来重定义它。一个BFC就是一个HTML盒子,它至少满足以下条件之一:
float
的值不为none
position
的值不为static
或relative
display
的值为table-cell
、table-caption
、inline-block
、flex
或inline-flex
overflow
的值不为visiable
创建一个块级格式化上下文
一个BFC可以显式触发。如果我们想创建之,我们只需给它添加上面提到的任何一个CSS样式。
比如,看下面的HTML:
1 2 3 |
<div class="container"> Some Content here </div> |
一个新的BFC可以通过给容器添加任意一个必要的CSS样式来创建,比如overflow: scroll
,overflow: hidden
,display: flex
,float: left
,或 display: table
。尽管上述条件都可以创建BFC,但也会产生一些其他效果,如:
display: table
可能引发响应性问题overflow: scroll
可能产生多余的滚动条float: left
将把元素移至左侧,并被其他元素环绕overflow: hidden
将裁切溢出元素
所以无论何时,当要创建一个BFC时,我们要基于需求选择最恰当的样式。为了保持一致性,我在本文的所有例子中均使用overflow: hidden
。
1 2 3 |
.container { overflow: hidden; } |
你可以自由选择使用除 overflow: hidden
之外的其他样式。
BFC中盒子的对齐
W3C规范道:
在BFC上下文中,每个盒子的左外侧紧贴包含块的左侧(从右到左的格式里,则为盒子右外侧紧贴包含块右侧),甚至有浮动也是如此(尽管盒子里的行盒子
Line Box
可能由于浮动而变窄),除非盒子创建了一个新的BFC(在这种情况下盒子本身可能由于浮动而变窄)。
简单来说,如上图所示,所以属于BFC的盒子都左对齐(在从左到右的格式下)并且它们的左外侧紧贴包含块的左侧。在最后一个盒子中我们可以看到尽管左侧存在一个浮动元素(棕色),另外一个元素(绿色)仍然紧贴包含块的左侧。该情况的产生原理将在下文关于文字环绕的部分中讨论。
BFC造成的外边距折叠
在常规流中,盒子从包含块的顶部开始一个个地垂直摆放。两个同胞盒子间的垂直举例由两个盒子各自的外边距所决定,但不是二者外边距之和。
为便于理解,我们看个例子。
在上图中,一个红盒子(div
)包含着两个同胞绿元素(p
),一个BFC已经创建了出来。
1 2 3 4 |
<div class="container"> <p>Sibling 1</p> <p>Sibling 2</p> </div> |
相应的CSS是:
1 2 3 4 5 6 7 8 |
.container { background-color: red; overflow: hidden; /* creates a block formatting context */ } p { background-color: lightgreen; margin: 10px 0; } |
理论上两个同胞元素间的外边距应当是二者外边距之和(20px)但实际上却是10px。这就是众所周知的外边距折叠(Collapsing Margins)。如果同胞元素外边距不同,将应用最大的那个。
使用BFC避免外边距折叠
在讨论了上面BFC折叠外边距的情况后,现在说避免折叠可能有点让人摸不着头脑。但我们必须牢记于心的一件事是,相邻块级盒子(同胞)之间的垂直外边距只有在它们处于同一个BFC时才会发生折叠。如果它们分属于不同的BFC,就不会折叠了。所以,通过创建新的BFC我们可以避免外边距折叠。
让我们在早前的例子中添加第三个同胞元素,现在HTML是:
1 2 3 4 5 |
<div class="container"> <p>Sibling 1</p> <p>Sibling 2</p> <p>Sibling 3</p> </div> |
CSS是:
1 2 3 4 5 6 7 8 |
.container { background-color: red; overflow: hidden; /* creates a block formatting context */ } p { background-color: lightgreen; margin: 10px 0; } |
结果和上面一样,即是说,折叠还是会发生并且三个同胞间分隔的垂直距离是10px。这是因为三个 p
标签都从属于同一个BFC。
现在我们修改第三个同胞元素,使之成为一个新的BFC的一部分。现在的HTML变成了:
1 2 3 4 5 6 7 |
<div class="container"> <p>Sibling 1</p> <p>Sibling 2</p> <div class="newBFC"> <p>Sibling 3</p> </div> </div> |
css:
块级格式化上下文(Block Formatting Context)是网页CSS视觉渲染的一部分,并用于决定块盒子的布局。在定位体系(Positioning Scheme)中它属于常规流(Normal Flow)。根据W3C所言:
浮动、绝对定位元素(
position
为absolute
或fixed
)、行内块元素display:inline-block
、表格单元格display:table-cell
、表格标题display:table-caption
以及overflow
属性值不为visible
的元素(除了该值被传播到视点viewport
的情况)将创建一个新的块级格式化上下文。
上面的引言差不多总结了一个BFC是如何形成的。但让咱们用另外一种更通俗易懂的方式来重定义它。一个BFC就是一个HTML盒子,它至少满足以下条件之一:
float
的值不为none
position
的值不为static
或relative
display
的值为table-cell
、table-caption
、inline-block
、flex
或inline-flex
overflow
的值不为visiable
创建一个块级格式化上下文
一个BFC可以显式触发。如果我们想创建之,我们只需给它添加上面提到的任何一个CSS样式。
比如,看下面的HTML:
1 2 3 |
<div class="container"> Some Content here </div> |
一个新的BFC可以通过给容器添加任意一个必要的CSS样式来创建,比如overflow: scroll
,overflow: hidden
,display: flex
,float: left
,或 display: table
。尽管上述条件都可以创建BFC,但也会产生一些其他效果,如:
display: table
可能引发响应性问题overflow: scroll
可能产生多余的滚动条float: left
将把元素移至左侧,并被其他元素环绕overflow: hidden
将裁切溢出元素
所以无论何时,当要创建一个BFC时,我们要基于需求选择最恰当的样式。为了保持一致性,我在本文的所有例子中均使用overflow: hidden
。
1 2 3 |
.container { overflow: hidden; } |
你可以自由选择使用除 overflow: hidden
之外的其他样式。
BFC中盒子的对齐
W3C规范道:
在BFC上下文中,每个盒子的左外侧紧贴包含块的左侧(从右到左的格式里,则为盒子右外侧紧贴包含块右侧),甚至有浮动也是如此(尽管盒子里的行盒子
Line Box
可能由于浮动而变窄),除非盒子创建了一个新的BFC(在这种情况下盒子本身可能由于浮动而变窄)。
简单来说,如上图所示,所以属于BFC的盒子都左对齐(在从左到右的格式下)并且它们的左外侧紧贴包含块的左侧。在最后一个盒子中我们可以看到尽管左侧存在一个浮动元素(棕色),另外一个元素(绿色)仍然紧贴包含块的左侧。该情况的产生原理将在下文关于文字环绕的部分中讨论。
BFC造成的外边距折叠
在常规流中,盒子从包含块的顶部开始一个个地垂直摆放。两个同胞盒子间的垂直举例由两个盒子各自的外边距所决定,但不是二者外边距之和。
为便于理解,我们看个例子。
在上图中,一个红盒子(div
)包含着两个同胞绿元素(p
),一个BFC已经创建了出来。
1 2 3 4 |
<div class="container"> <p>Sibling 1</p> <p>Sibling 2</p> </div> |
相应的CSS是:
1 2 3 4 5 6 7 8 |
.container { background-color: red; overflow: hidden; /* creates a block formatting context */ } p { background-color: lightgreen; margin: 10px 0; } |
理论上两个同胞元素间的外边距应当是二者外边距之和(20px)但实际上却是10px。这就是众所周知的外边距折叠(Collapsing Margins)。如果同胞元素外边距不同,将应用最大的那个。
使用BFC避免外边距折叠
在讨论了上面BFC折叠外边距的情况后,现在说避免折叠可能有点让人摸不着头脑。但我们必须牢记于心的一件事是,相邻块级盒子(同胞)之间的垂直外边距只有在它们处于同一个BFC时才会发生折叠。如果它们分属于不同的BFC,就不会折叠了。所以,通过创建新的BFC我们可以避免外边距折叠。
让我们在早前的例子中添加第三个同胞元素,现在HTML是:
1 2 3 4 5 |
<div class="container"> <p>Sibling 1</p> <p>Sibling 2</p> <p>Sibling 3</p> </div> |
CSS是:
1 2 3 4 5 6 7 8 |
.container { background-color: red; overflow: hidden; /* creates a block formatting context */ } p { background-color: lightgreen; margin: 10px 0; } |
结果和上面一样,即是说,折叠还是会发生并且三个同胞间分隔的垂直距离是10px。这是因为三个 p
标签都从属于同一个BFC。
现在我们修改第三个同胞元素,使之成为一个新的BFC的一部分。现在的HTML变成了:
1 2 3 4 5 6 7 |
<div class="container"> <p>Sibling 1</p> <p>Sibling 2</p> <div class="newBFC"> <p>Sibling 3</p> </div> </div> |
css: