BFC
BFC是 块级格式化上下文。
二、如何创建(开启)BFC?
创建 BFC 并不是通过一个特定的 CSS 属性 bfc: true 来实现的,而是通过应用某些特定的 CSS 属性来“触发”或“开启”一个元素的 BFC 特性。以下是常见的触发方式:
-
根元素
<html>:- 页面最大的 BFC 就是
<html>元素。
- 页面最大的 BFC 就是
-
浮动元素:
float的值不为 none(即left或right)。
-
绝对定位元素:
- position 的值为
absolute或fixed。
- position 的值为
-
行内块元素:
- display 的值为
inline-block。
- display 的值为
-
表格单元格:
- display 的值为 table-cell 或 table-caption。
-
弹性盒子(Flexbox)的子项:- display 的值为 flex 或 inline-flex 的直接子元素。
-
网格布局(Grid)的子项:- display 的值为 grid 或 inline-grid 的直接子元素。
-
overflow 属性:
overflow的值不为 visible(即hidden,auto,scroll)。这是最常用、副作用最小的创建 BFC 的方法。
-
display: flow-root; :
- 这是一个专门为了创建 BFC 而生的新属性。它的唯一作用就是创建一个无副作用的 BFC,是目前最推荐的现代方法。
小结:在日常开发中,最常用且最推荐的创建 BFC 的方法是 overflow: hidden; 和 display: flow-root;。
三、BFC 解决了什么问题?(BFC 的应用)
BFC 的核心价值在于它的“隔离”和“内部特殊布局规则”。正是这些特性,让它能巧妙地解决以下几个经典的 CSS 布局难题。
1. 解决问题一:清除内部浮动(防止父元素高度塌陷)
这是 BFC 最最最经典的应用场景。
-
问题描述:当一个父元素内部只包含浮动元素时,由于浮动元素脱离了正常的文档流,父元素会无法感知其高度,导致父元素的高度“塌陷”为 0。这会影响后续元素的布局。
-
示例:
codeHtml
<div class="parent"> <div class="child"></div> </div> <div class="footer">Footer</div>codeCSS
.parent { border: 2px solid red; } .child { float: left; width: 100px; height: 100px; background: lightblue; }在这个例子中,红色的边框会“塌陷”成一条线,因为 .parent 的高度为 0。
-
BFC 解决方案:给父元素 .parent 触发 BFC。
codeCSS
.parent { border: 2px solid red; overflow: hidden; /* 触发 BFC */ /* 或者 display: flow-root; */ } -
原理解释:BFC 的一个重要规则是:在计算 BFC 的高度时,其内部的浮动元素也参与计算。 当 .parent 成为一个 BFC 后,它就像一个负责任的家长,会去“关照”它内部所有调皮的浮动孩子,把它们的高度也算作自己的高度。这样,父元素的高度就被正确地撑开了。
2. 解决问题二:防止外边距折叠(Margin Collapse)
-
问题描述:在正常的文档流中,相邻的
两个块级元素的**垂直外边距**会发生“折叠”,即取两者中较大的那个值作为它们之间的间距,而不是简单相加。这在兄弟元素之间和父子元素之间都可能发生。 -
示例(兄弟元素) :
codeHtml
<div style="margin-bottom: 20px; background: lightcoral;">Box 1</div> <div style="margin-top: 30px; background: lightskyblue;">Box 2</div>Box 1 和 Box 2 之间的实际间距是 30px,而不是 20px + 30px = 50px。
-
BFC 解决方案:将其中一个元素用一个 BFC 容器包裹起来。
codeHtml
<div style="margin-bottom: 20px; background: lightcoral;">Box 1</div> <div style="overflow: hidden;"> <!-- 创建一个 BFC 容器 --> <div style="margin-top: 30px; background: lightskyblue;">Box 2</div> </div> -
原理解释:BFC 的另一个重要规则是:BFC 是一个独立的容器,它内部的元素外边距不会与外部的元素发生折叠。 当我们用一个 BFC 包裹住 Box 2 后,Box 2 的 margin-top 就被“关”在了这个 BFC 内部,它只能和 BFC 容器的边框发生关系,而无法“穿透” BFC 去和外面的 Box 1 发生折叠。
3. 解决问题三:自适应两栏(或三栏)布局
-
问题描述:我们想实现一个经典的布局:左边栏固定宽度,右边栏自适应剩余宽度。如果简单地让左边栏 float: left,右边栏不设置浮动,右边栏的文字会环绕在左边栏周围,其背景和边框会延伸到左边栏的下方。
-
示例:
codeHtml
<div class="left">Left</div> <div class="right">Right content will wrap around the left floated element...</div>codeCSS
.left { float: left; width: 200px; height: 150px; background: lightcoral; } .right { height: 200px; background: lightskyblue; }你会看到,蓝色的背景铺满了整个宽度,覆盖了左边栏的下方。
-
BFC 解决方案:给右边栏 .right 触发 BFC。
codeCSS
.right { height: 200px; background: lightskyblue; overflow: hidden; /* 触发 BFC */ } -
原理解释:BFC 的第三个重要规则是:
BFC 的区域不会与浮动元素的区域发生重叠。 当 .right 成为一个 BFC 后,它会感知到旁边有一个浮动元素 .left 占了空间。为了不与它重叠,BFC 会自动计算自己可用的剩余宽度,并收缩自己的布局范围,从而完美地实现了自适应布局。