对基本视觉模型的总结( visual formatting mo
参考资料
CSS2.2标准第九章:
《CSS权威指南》第七章
基本视觉格式化
什么是 visual formatting model
how user agents process the document tree for visual media.
简言之,浏览器怎么处理文档树,呈现最终布局效果就是在这部分描述的。把这部分看完就能把一下知识点串到一起了:
- 盒模型
- IFC
- BFC
- 浮动
- 绝对定位
- 文档流
- .....
下面我根据visual formatting model讲的规则,阐述一下从元素到盒子,再从盒子到最后的布局效果的大致过程。
盒子的产生
一个HTML元素会产生0或多个盒子,产生哪些盒子,这些盒子是什么类型的由display属性决定。我们以下面的属性值为例,表述display属性对盒子的影响。
display: block
一个元素产生一个块级的principal box
display: inline-block
产生一个行内的块级盒子,它的内部按照块级盒子布局,它自身表现为行内盒子。
display: inline
产生一个或多个行内盒子。
display: list-item
产生一个块级的principal box和一个 marker box
display: none
不在formatting structure 中出现,不产生盒子。
<div>
u
</div>
匿名块级盒与匿名行内盒
下面的这种情况,好像div里面有一个inline的文本,和一个块级的p元素。实际在处理的时候会给inline元素套上一个匿名的块级盒子。
<DIV>
Some text
<P>More text
</DIV>
产生匿名块级盒
换句话说,如果一个块级的直接子元素里面有一个block元素,那么会给其他行内元素套上一个匿名块级盒。
盒子怎么排列
CSS2.2规定,一个盒子可能通过以下三种方式进行布局:
- normal flow, CSS2.2中, normal flow包含对块级元素的块级格式化(BFC),对行内元素的行内格式化(IFC),和对两者的相对定位(relative positioning)。
- 浮动。 In the float model, a box is first laid out according to the normal flow, then taken out of the flow and shifted to the left or right as far as possible. Content may flow along the side of a float.
- 绝对定位。In the absolute positioning model, a box is removed from the normal flow entirely (it has no impact on later siblings) and assigned a position with respect to a containing block.
position和float决定盒子采取哪种定位方式
position对布局的影响
static
盒子通过normal flow的规则进行布局。
relative
盒子通过normal flow的规则进行布局,然后偏移。
absolute
position为absolute的元素脱离文档流,不对后边的兄弟元素造成影响。
fixed
根据viewport进行定位,表现类似于absolute,但不会随着页面滚动而移动。
正常流 Normal flow
每个正常流中的盒子从属于一个布局上下文,CSS2.2中有三种上下文:table, block, inline。CSS3中有新的上下文引入。
table布局
这里不对它的布局方式展开说明,详见: Tables
BFC(Block formatting context)
下面几种情况会为内容创建新的块级格式化上下文:
- 浮动,float不为none
- 对定位元素, display: absolute
- 根元素
- overflow不为visible的
在BFC中的盒子从上到下,一个接一个排列,上下两个盒子的距离由margin决定。
创建BFC示例:
<div style="float: left">
<div>
some text
</div>
<div>
other text
</div>
</div>
创建IFC
BFC的一些布局规则:
- 盒子从上到下垂直排列
- 盒子左外边沿和容器左边沿接触
- 盒子上下间距由margin决定
- 邻近盒子会产生外边距折叠(margin collapse)
IFC
一个块级盒内部如果只有行内盒子,那么会创建一个行内上下文,这个块级容器内部的盒子按照IFC的规则水平排列。
创建IFC示例:
<div>
some text
<span>other content</span>
</div>
例如这个例子,div会创建一个块级盒,这个块级盒里面没有其他块级元素了。所以会为内容创建一个IFC,处在IFC下面的行内元素按照IFC的规则进行水平布局。
创建IFCIFC的一些布局规则:
- 盒子水平从左往右排列
- 盒子的垂直方向可能以多种方式对其(baseline, bottom等)
- 水平的margin, padding, border起作用。
- 如果一个盒子水平放置不下,可能会被分开换到下一行。
- 如果水平方向有空余,可以使用text-align设置水平方向对其方式。
总结
视觉模型描述了HTML元素怎么产生盒子,以及盒子在不同的情况下怎么布局。
- 一个元素会产生0到多个盒子,如display:none不产生盒子。display: list-item会产生两个盒子
- 根元素、float、绝对定位等情况会产生一个BFC,它里面的盒子按照BFC的规则布局。
- 如果一个块级容器内部只有行内元素,则会为内部元素产生一个IFC。
- 在BFC下的盒子是从上往下排列的,
- IFC下的盒子是从左往右排列的。