混淆视听的 Block & Box
在真正入正题之前,我们先来聊清楚,块(block)与盒子(box)的概念。
块 Block
MDN 说,Block 是一个抽象的概念,它描述的是文档流上一个独立的区域。块与块之间在垂直方向上按照顺序依次堆叠。
从定义上我们似乎无法提取到任何有用的信息,但是从特性上我们可以间接的做一些判断。也就是第二句,在垂直方向上按照顺序依次堆叠,这就说明,块的一个最明显的特点就是,独占一行,但这并不是块本身具有的属性,只是因为块能创建块级盒子。
盒子 Box
盒子也是一个抽象的概念,但是它是由 CSS 引擎根据文档中的内容所创建的,用于文档元素的定位、布局和格式化的,真实存在的布局体。
可以说,在 css 布局里,一切皆盒子,这有点像我们现在的图像世界,一切皆像素。盒子的类型有很多,这里我们就不做过多展开了。
块级元素(Block level element)
元素的
display为block、list-item、table时,该元素将成为块级元素。元素是否是块级元素仅是元素本身的属性,并不直接用于格式化上下文的创建或布局。
这段话的前一句好理解,是对块级元素的一个定义,后一句其实是强调,元素并不是真正参与布局的个体,真正参与布局的都是盒子。
块级盒子(Block level box)
由块级元素生成。一个块级元素至少会生成一个块级盒子,但也有可能生成多个(例如列表项元素)。
这个并不矛盾,我们来顺一顺,首先块级盒子由块级元素生成,而块级元素并不参与布局规则,真正参与布局都是盒子。
姗姗来迟 BFC
讲了这么多,总算是来到正题了,首先来看定义:
BFC(
block formatting context)块级格式化上下文,它是页面中的一块渲染区域,并且有一套属于自己的渲染规则,它决定了元素如何对齐内容进行布局,以及与其他元素的关系和相互作用。 当涉及到可视化布局的时候,BFC提供了一个环境,HTML元素在这个环境中按照一定规则进行布局。
几点要意
block formatting context即:block-level box的Formatting Context,说人话就是,一个规定了块级盒子(block-level box)布局方式(Formatting)的区域(Context)。BFC是一个区域,这个区域并不一定是由块盒子形成的。
形成条件
- 根元素
html float不为nonedisplay为inline-block、table-cell、table-captionposition为absolute、fixedoverflow不为visible
内部规则
- 内部的
Box会在垂直方向上一个接一个的放置 - 属于同一个
BFC的两个相邻Box的margin会发生重叠(塌陷),与方向无关 - 常规流和浮动流布局环境下,每个元素的左外边距与包含块的左边界相接触(从左向右),绝对定位流除外(布局流一共分三种:普通流、浮动流、绝对定位流)
- 计算
BFC的高度时,内部浮动子元素也参与计算,即不会发生高度塌陷
外部规则
BFC区域不会与外部float元素区域发生重叠BFC是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然。即BFC与外部块级元素不存在margin重叠问题