块级格式化上下文
块级格式化上下文(BFC)是网页的视觉 CSS 渲染的一部分。它是块级盒子的布局发生的区域,也是浮动与其他元素交互的区域。
块级格式化上下文至少由以下一种情况创建
- 文档的根元素(
<html>
)。 - 浮动(
不是float
none
的元素)。 - 绝对定位的元素(
为position
absolute
或fixed
的元素)。 - 内联块(
的元素)。display: inline-block
- 表格单元格(
的元素,这是 HTML 表格单元格的默认值)。display: table-cell
- 表格标题(
的元素,这是 HTML 表格标题的默认值)。display: table-caption
、display: table
table-row
、table-row-group
、table-header-group
、table-footer-group
(分别为 HTML 表格、表格行、表格主体、表格标题和表格页脚的默认值)或inline-table
的元素隐式创建的匿名表格单元格。
值不为overflow
visible
和clip
的块级元素。
的元素。display: flow-root
元素和默认值为<button>
display: flow-root
的按钮
类型。<input>
、contain: layout
content
或paint
的元素。- 如果 flex 项目(
或display: flex
inline-flex
的元素的直接子元素)本身既不是flex
容器,也不是grid
容器,也不是table
容器。 - 如果 grid 项目(
或display: grid
inline-grid
的元素的直接子元素)本身既不是flex
容器,也不是grid
容器,也不是table
容器。 - 多列容器(
或column-count
不为column-width
auto
的元素,包括column-count: 1
的元素)。
,即使column-span: all
column-span: all
元素未包含在多列容器中。
格式化上下文影响布局,因为建立新块级格式化上下文的元素将
- 包含内部浮动。
- 排除外部浮动。
- 抑制
margin collapsing
。
通过将元素的 (display
设置为 flex
、grid
、inline-flex
或 inline-grid
,定义的弹性盒和网格容器会建立一个新的弹性盒或网格格式化上下文。它们类似于块级格式化上下文,但弹性盒或网格容器内部没有浮动子元素可用,但这些格式化上下文会排除外部浮动并抑制外边距合并。
示例
让我们看几个例子,看看创建新的 BFC 的效果。
包含内部浮动
在下面的示例中,我们有一个浮动内容,其高度与它旁边的内容相同。我们在一个应用了 border
的 <div>
中有一个浮动元素。该 <div>
的内容与浮动元素并排浮动。由于浮动内容的高度高于它旁边的内容,现在 <div>
的边框穿过浮动元素。如 流内和流外元素指南 中所述,浮动元素已移出流,因此 <div>
的 background
和 border
只包含内容,而不包含浮动元素。
使用 overflow: auto
设置 overflow: auto
或设置除 overflow: visible
的初始值之外的其他值,会创建一个包含浮动元素的新 BFC。我们的 <div>
现在成为我们布局中的一个迷你布局。任何子元素都将包含在其中。
使用 overflow
创建新的 BFC 的问题是,overflow
属性用于告诉浏览器如何处理溢出内容。在某些情况下,你会发现当你纯粹为了创建 BFC 使用此属性时,会出现不必要的滚动条或被剪裁的阴影。此外,它可能对未来的开发者来说不可读,因为他们可能不清楚你为什么要将 overflow
用于此目的。如果你使用 overflow
,最好在代码中添加注释以解释原因。
使用 display: flow-root
display: flow-root
值允许我们在没有任何其他潜在问题的情况下创建一个新的 BFC。在包含块上使用 display: flow-root
会创建一个新的 BFC。
在 <div>
上使用 display: flow-root;
后,该容器内的所有内容都参与该容器的块级格式化上下文,并且浮动元素不会从元素的底部突出。
当你理解你正在创建一个在创建新上下文方面类似于 root
元素(浏览器中的 <html>
元素)的行为时,flow-root
的值名称就说得通了。
这是 <button>
元素和按钮 <input>
类型的默认渲染方式,这意味着按钮会创建一个新的 BFC,只要它们的 display
值没有设置为不会自动创建新的 BFC 的值。
HTML
<section>
<div class="box">
<div class="float">I am a floated box!</div>
<p>I am content inside the container.</p>
</div>
</section>
<section>
<div class="box" style="overflow:auto">
<div class="float">I am a floated box!</div>
<p>I am content inside the <code>overflow:auto</code> container.</p>
</div>
</section>
<section>
<div class="box" style="display:flow-root">
<div class="float">I am a floated box!</div>
<p>I am content inside the <code>display:flow-root</code> container.</p>
</div>
</section>
CSS
section {
height: 150px;
}
.box {
background-color: rgb(224 206 247);
border: 5px solid rebeccapurple;
}
.box[style] {
background-color: aliceblue;
border: 5px solid steelblue;
}
.float {
float: left;
width: 200px;
height: 100px;
background-color: rgb(255 255 255 / 50%);
border: 1px solid black;
padding: 10px;
}
排除外部浮动
在下面的示例中,我们使用 display:flow-root
和浮动元素,创建了两个并排的框,展示了在正常流中的元素会建立一个新的 BFC,并且不会与同一块级格式化上下文中的任何浮动元素的边距框重叠。
HTML
<section>
<div class="float">Try to resize this outer float</div>
<div class="box"><p>Normal</p></div>
</section>
<section>
<div class="float">Try to resize this outer float</div>
<div class="box" style="display:flow-root">
<p><code>display:flow-root</code></p>
</div>
</section>
CSS
section {
height: 150px;
}
.box {
background-color: rgb(224 206 247);
border: 5px solid rebeccapurple;
}
.box[style] {
background-color: aliceblue;
border: 5px solid steelblue;
}
.float {
float: left;
overflow: hidden; /* required by resize:both */
resize: both;
margin-right: 25px;
width: 200px;
height: 100px;
background-color: rgb(255 255 255 / 75%);
border: 1px solid black;
padding: 10px;
}
防止外边距合并
你可以创建一个新的 BFC 来避免两个相邻元素之间的 外边距合并。
外边距合并示例
在这个示例中,我们有两个相邻的 <div>
元素,每个元素都有 10px
的垂直外边距。由于外边距合并,它们之间的垂直间隙是 10px
,而不是我们预期的 20px
。
<div class="blue"></div>
<div class="red"></div>
.blue,
.red {
height: 50px;
margin: 10px 0;
}
.blue {
background: blue;
}
.red {
background: red;
}
防止外边距合并
在这个示例中,我们将第二个 <div>
包裹在一个外部 <div>
中,并通过在外部 <div>
上使用 overflow: hidden
创建了一个新的 BFC。这个新的 BFC 阻止了嵌套的 <div>
的外边距与外部 <div>
的外边距合并。
<div class="blue"></div>
<div class="outer">
<div class="red"></div>
</div>
.blue,
.red {
height: 50px;
margin: 10px 0;
}
.blue {
background: blue;
}
.red {
background: red;
}
.outer {
overflow: hidden;
background: transparent;
}
规范
规范 |
---|
CSS 显示模块级别 3 # 块级格式化上下文 |