参考链接
BFC
BFC 定义
BFC (Block Formatting Context) 直译为”块级格式化上下文”。它是一个独立的渲染区域,只有 Block-level Box 参与, 它规定了内部的 Block-level Box 如何布局,并且与这个区域外部毫不相干。
BFC 布局规则:
- 内部的 Box 会在垂直方向,一个接一个地放置。
- Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠。
- 每个元素的左 margin, 与包含块的左 border 相接触 (对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
- BFC 的区域不会与外部浮动盒子重叠。
- BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算 BFC 的高度时,浮动元素也参与计算
- HTML 结构中,当构建 BFC 区域的元素紧接着一个浮动盒子时,即该浮动盒子的兄弟节点,BFC 区域会首先尝试在浮动盒子的旁边渲染,但若宽度不够,就在浮动元素的下方渲染。[看这里]
BFC 的生成
- 根元素,即
<html>
标签 float
属性不为none
position
为absolute
或fixed
display
为flow-root
,inline-block
,table-cell
,table-caption
,flex
,inline-flex
,grid
、inline-grid
(display
值为flex
或inline-flex
元素的直接子元素
display
值为grid
或inline-grid
元素的直接子元素)overflow
不为visible
,为auto、scroll、hidden
的块元素(子元素生效)
简单总结
因为BFC
内部的元素和外部的元素绝对不会互相影响,因此,
当BFC
外部存在浮动时,它不应该影响 **BFC**
内部Box的布局,BFC
会通过变窄,而不与浮动有重叠。
同样的,当 BFC
内部有浮动时,为了不影响外部元素的布局,BFC
计算高度时会包括浮动的高度。
个人补充
block formatting context
- block container => block-level box
inline formatting context
- line box => inline-level box
flex formatting context
- flex container => flex item
grid formatting context
- grid container => grid item
不在正常流中,且其中可包含文字的
flex 的元素是 FFC,flex item 里面才是 BFC
grid 元素是 GFC,grid item 里面才是 BFC
往 block container 内放另一个 block container,
block container 内的 block container = block container + block-level box = block box = block
block + overflow: visible 不产生 BFC,外面有 BFC,内部不产生 BFC(正常流中的特性)
在生成 BFC 时候,flex 、grid、overflow 管的都是内部块级元素的排列,而不是自身的
下面以边框重叠的解决方案为例,简单对比一下几种生成 BFC 的方式
HTML
<div class="red"></div>
<div class="blue"></div>
CSS
.red {
width: 100px;
height: 100px;
background-color: red;
margin-bottom: 100px;
}
.blue {
width: 100px;
height: 100px;
background-color: blue;
margin-top: 100px;
}
float
.blue {
float: left;
}
position
.blue {
position: absolute;
}
overflow
.blue {
overflow: hidden;
}
flex
.blue {
display: flex;
}
我们发现,float
和 position
对应的解决方案是有效的,而 overflow
和 flex
对应的解决方案是无效的,这是为什么呢?
为了解决问题,我们先来对比一下下面几个属性在 MDN 或 W3C 中的定义,不难发现,
float
和 position
强调的是元素本身相对于容器的属性,
而 overflow
和 flex
则强调的是元素的内容 ( 或子元素 ),或者说,强调的是元素本身为框架。
所以,给当前元素设置 flex
或者 overflow
可能达不到我们想要的 BFC 的效果,因为它们的 BFC 特性是针对子元素而言,而非自身。
float
CSS 属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。CSS
position
属性用于指定一个元素在文档中的定位方式CSS属性
overflow
定义当一个元素的内容太大而无法适应 块级格式化上下文 时候该做什么。
所以,在原来的例子的基础上,套上一个父元素,在父元素上设置这些属性即可。
<div class="red"></div>
<div class="blue-father">
<div class="blue"></div>
</div>
overflow
.blue-father {
overflow: hidden;
}
flex
.blue-father {
display: flex;
}
解决方案有效。