持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
什么是BFC
BFC 全称是 Block Formatting Context,即块格式化上下文。它是 CSS2.1 规范定义的,关于 CSS 渲染定位的一个概念。它是一个独立的渲染区域,只有 Block-level box 参与, 它规定了内部的 Block-level Box 如何布局,并且与这个区域外部毫不相干。
BFC 布局规则
- 内部的 Box 会在垂直方向,一个接一个地放置;
- Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠;
- 每个元素的 margin box 的左边, 与包含块 border box 的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。;
- BFC 的区域不会与 float box 重叠,常用来清除浮动和布局。;
- BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。;
- 计算 BFC 的高度时,浮动元素也参与计算;
会生成 BFC 的元素
- 根元素或其它包含它的元素;
- 浮动 (元素的
float
不为none
); - 绝对定位元素 (元素的
position
为absolute
或fixed
); - 行内块
inline-blocks
(元素的display: inline-block
); - 表格单元格(元素的
display: table-cell
,HTML 表格单元格默认属性); overflow
的值不为visible
的元素;- 弹性盒 flex boxes (元素的
display: flex
或inline-flex
);
BFC 的范围
BFC 的范围在 MDN 中是这样描述的。
A block formatting context contains everything inside of the element creating it that is not also inside a descendant element that creates a new block formatting context.
中文的意思一个 BFC 包含创建该上下文元素的所有子元素,但不包括创建了新 BFC 的子元素的内部元素。
插入一段代码方便理解
<div class='div_1 BFC'>
<div class='div_2'>
<div class='div_3'></div>
<div class='div_4'></div>
</div>
<div class='div_5 BFC'>
<div class='div_6'></div>
<div class='div_7'></div>
</div>
</div>
div_1
创建了一个块格式上下文,这个上下文包括了div_2
、div_3
、div_4
、div_5
。即div_2
中的子元素也属于div_1
所创建的 BFC。但由于div_5
创建了新的 BFC,所以div_6
和div_7
就被排除在外层的 BFC 之外。
这就代表着一个元素不能同时存在于多个 BFC 中。
BFC 的一个最重要的效果是,让处于 BFC 内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响。这是利用 BFC 清除浮动所利用的特性。
BFC 的常用方式
子级浮动导致父级高度塌陷
<style type="text/css">
.box{
width: 900px;
background: black;
height: 300px; // 增加高度
}
.box1{
height: 300px;
width: 300px;
background: red;
float: left;
}
.box2{
height: 300px;
width: 300px;
background: blue;
float: left;
}
</style>
......
<div class="box">
<div class="box1"></div>
<div class="box2"></div>
</div>
上面的代码定义了3个块,一个父级包含了两个子集,但是父级的背景颜色无法显示,是因为子集元素浮动导致了父级高度的塌陷。
在为box设置BFC后,box的高度才能找回来。
从而显示出正确的样式。
子级 margin-top 将父级带下 为父级触发 BFC
一个盒子有上边距 另一个有下边距 会出现 margin 边距的重叠问题
并列盒子的 margin 重写 =>双 margin 的重叠
-> 取大值 并不是他们相加之和 也就是谁大听谁的
要将黑色块中的小红块下移一点,直接使用了 margin-top,结果黑块一起下移了。
<style type="text/css">
.box{
width: 300px;
height: 300px;
background: black;
}
.box1{
height: 100px;
width: 100px;
background: red;
margin-top: 50px;
}
</style>
......
<div class="box">
<div class="box1"></div>
</div>
而设置了 BFC 后,就能正确的下浮红色块
margin 的兼容问题:margin top 的传递问题
大盒子里面嵌套小盒子 给小盒子加 margin-top 不但没有实现和大盒子之间的间距 反而传递给大盒子身上 导致整体下移动
如何解决BFC
- overflow:hidden 解决 margin-top 的传递问题(此处并没有溢出隐藏)
- padding- 方位:1px 这种方法影响最后实际宽高 需要在 width/height 上基础上减掉才不会影响最后实际的宽高
- border-top:1px 这种方法会影响最后实际的高度 需要在高度 height 上基础上减掉 才不会影响最后实际的高度
- 给子元素的 margin-top 的值改成父元素的 padding-top, 这样就避免使用 margin-top 值导致传递的问题