CSS 视觉格式化模型
W3C: http://www.ayqy.net/doc/css2-1/visuren.html
MDN: https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Visual_formatting_model
图示
(匿名) 块盒
原子行内级盒
行内级盒(匿名) 行内盒
行内格式化上下文
display { block | list-item | table }
块级替换元素, 表格元素
创建: 块级格式化上下文 (BFC)
创建: 行内格式化上下文 (IFC)
非替换行内块, 非替换表格单元
行内级替换元素, 行内表格元素
display { inline | inline-block | inline-table }
非替换行内元素
Case 1: 块级元素 in 行内级元素
[W3C] 当行内盒包含流内块级盒时,该行内盒(及与它处于同一行盒里的行内祖先)会打破周围的块级盒(以及任何连续的或只被可合并的空白符和/或流外元素隔开的块级兄弟),把行内盒分成两个盒(即使有一边是空的),分别位于块级盒的两边。拆分前的行盒与拆分后的行盒都被包进匿名块盒,并且该块级盒作为这些匿名盒的兄弟。
<span> <span>行内级元素</span> <p>块级元素</p> Inline Text </span>
块级元素
Inline TextCase 2: float
vs display:inline-block
[W3C] 然而,挨着浮动(盒)创建的当前及后续的行盒,会根据需要被缩短,以便给浮动(盒)的外边距框让出空间。
<div> <span style="float: left;">浮动盒</span> <p style="display: inline-block;">原子行内级盒</p> </div>
原子行内级盒
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur quas quisquam beatae illo, sit aliquid. Debitis architecto distinctio perspiciatis commodi!
Lorem ipsum dolor sit amet commodi!
原子行内级盒
Case 3: float
vs overflow:hidden
[W3C] 表格、块级替换元素或常规流中建立了新的块格式化上下文的元素(例如一个’overflow’不为’visible’的元素)不能和与元素自身处于同一块格式化上下文中的任何浮动(盒)的外边距框重叠。
<div> <span style="float: left;">浮动元素</span> <p style="overflow: hidden;">块级元素</p> </div>
Lorem ipsum dolor sit amet commodi!
块级元素 [MDN]
- 条件:
display
{block
|list-item
|table
} - 生成: 块级盒 (主要 + 额外)
行内级元素 [MDN]
- 条件:
display
{inline
|inline-block
|inline-table
} - 生成: 行内级盒
块级盒 [W3C]
参与块级格式化上下文
1. 块盒
块级盒 ∩ 块容器盒
- 除了: 表格元素, 替换元素
2. 匿名块盒
3. 块容器盒
只包含块级盒 或 只包含行内级盒
- 包括: 非替换行内块, 非替换表格单元
行内级盒 [W3C]
1. 行内盒
其内容参与父容器的行内格式化上下文 (IFC)
- 条件: 非替换行内元素
2. 匿名行内盒
3. 原子行内级盒
其内容参与父容器的行内格式化上下文 (IFC)
- 包括: 行内级替换元素, 行内块元素, 行内表格元素
块级格式化上下文 [W3C, MDN]
- 包含: 块级盒
规则
- 从包含块的顶部开始,盒在垂直方向一个接一个地放置。
- 两个兄弟盒之间的垂直距离由 ‘margin’ 属性决定。
- 同一 BFC 中的相邻块级盒之间的垂直外边距会合并。
- 每个盒的左外边界挨着包含块的左外边界(从右向左反之亦然),
即使存在浮动这也成立,除非该盒建立了一个新的 BFC。
条件
将为其内容创建新的 BFC
- 浮动
float
{left
|right
}
- 绝对定位元素
position
{absolute
|fixed
}
- 不是块盒的块容器盒
display
{inline-*
|table-*
} - {table-column
|table-column-group
}
- ‘overflow’ 不为 ‘visible’ 的块盒
overflow
{auto
|hidden
|scroll
}
- 根元素或其父容器:
<html>
行内格式化上下文 [W3C]
- 包含: 行内级盒
规则
- 从包含块的顶部开始,盒在水平方向一个接一个地放置。
- 盒可能会以不同的方式垂直对齐:以它们的底部或者顶部对齐,或者以它们里面的文本的基线对齐。
行盒
包含来自同一行的盒的矩形区域
- 行盒高度 ≥ 最高的盒的高度
- 当盒高度 < 行盒高度,它的垂直对齐方式由 ‘vertical-align’ 决定。
- 当所有盒的总宽度 < 行盒宽度,它们的 水平分布 由 ‘text-align’ 决定。
- 当多个盒在水平方向上不能共存于一个行盒时,它们会被分到两个或多个垂直堆叠行盒里。
- 行框没有垂直间隔地堆放(除非在其它地方有特别说明)并且它们不会重叠。
- 当行内盒超出行盒宽度时,它会被分成几个盒,并且这些盒会跨多行盒分布,
它的外边距,边框和内边距在发生分割的地方将没有视觉效果,
如果一个行内块无法分割(例white-space:nowrap
),那么它会从行盒溢出。 - 一般来说,一个行盒的左边界挨着其包含块的左边界(从右向左反之亦然),
然而,浮动盒可能会跑到包含块边界与行盒边界之间。