# 10 视觉格式化模型详解
> by [binlv](https://binlv.top)
[TOC]
## 10.1 "containing block" 的定义
元素盒子的位置和大小有时是相对于某个矩形---元素的 **包含块(containing block)** 来计算的。元素的包含块的定义如下:
1. 根元素所在的包含块是一个称为 **初始包含块 (initial containing block)** 的矩形。对于连续媒体,它具有视口的尺寸并锚定在画布原点;它是分页媒体的页面区域。初始包含块的'direction'属性与根元素相同。
2. 对于其他元素,如果元素的定位(position) 是 'relative' 或 'static',则包含块由最近的祖先盒子的内容边缘形成,该祖先盒子是块容器或建立格式化上下文。
3. 如果元素具有'position:fixed',则在连续介质的情况下由视口建立包含块或者在分页介质的情况下由页面区域建立包含块。
4. 如果元素具有'position:absolute',则包含块由最近的祖先以'absolute','relative'或'fixed'的'position'按以下方式建立:
1. 在祖先是内联元素的情况下,包含块是围绕为该元素生成的第一个和最后一个内联框的填充框的边界框。在CSS 2.2中,如果内联元素被分割成多行,那么包含块是未定义的。
2. 否则,包含块由祖先的填充边缘形成
如果没有这样的祖先,则包含块是初始包含块。
在分页媒体中,绝对定位的元素相对于其包含的块被定位而忽略任何分页符(就像文档是连续的)。该元素随后可能会分成几页。
对于绝对定位的内容,这些内容可以解析页面以外的页面位置(当前页面),或者解析为当前页面上已经被渲染用于打印的位置,打印机可以将内容
* 在当前页面的另一个位置上
* 在后续页面上,或
* 可能省略它
> 请注意,分成多页的块级元素可能在每个页面上具有不同的宽度,并且可能存在设备特定的限制。
***一个小例子:***
~~~html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
<HEAD>
<TITLE>Illustration of containing blocks</TITLE>
</HEAD>
<BODY id="body">
<DIV id="div1">
<P id="p1">This is text in the first paragraph...</P>
<P id="p2">This is text <EM id="em1"> in the
<STRONG id="strong1">second</STRONG> paragraph.</EM></P>
</DIV>
</BODY>
</HTML>
~~~
在没有定位的情况下,上面例子中的包含块(C.B.)关系如下:
| 盒子 | 对应的包含块 |
| --- | --- |
| html | initial C.B. (UA-dependent) |
| body | html |
| div1 | body |
| p1 | div1 |
| p2 | div1 |
| em1 | p2 |
| strong1 | p2 |
如果我们对 `div1` 进行定位:
```css
#div1 { position: absolute; left: 50px; top: 50px }
```
其包含块不再是“body”,而变成了初始包含块(因为没有其他定位的祖先盒子)。
如果我们也对 `em1` 进行定位:
```css
#div1 { position: absolute; left: 50px; top: 50px }
#em1 { position: absolute; left: 100px; top: 100px }
```
则对应的包含块关系如下:
| 盒子 | 对应的包含块 |
| --- | --- |
| html | initial C.B. (UA-dependent) |
| body | html |
| div1 | initial C.B. |
| p1 | div1 |
| p2 | div1 |
| em1 | div1 |
| strong1 | em1 |
通过定位“em1”,其包含块成为最接近定位的祖先盒(即由“div1”生成的)。
## 10.2 "width"属性相关说明
## 10.3 "width"和"margin"值的计算
一个元素的'width','margin-left','margin-right','left' 和 'right' 这些用于布局的属性的值,取决于生成的盒子的类型和相互之间的类型。(用于布局的值有时称为使用的值)原则上,所使用的值与计算值相同,'auto' 由一些合适的值代替,百分比基于包含块计算,但也有例外。需要区分以下情况:
## 10.4 最小宽度 "min-width" 和 最大宽度 "max-width"
## 10.5 "height"属性相关说明
## 10.6 "height"和"margin"值的计算
## 10.7 最小高度 "min-height" 和 最大高度 "max-height"
## 10.8 行高相关的计算: 'line-height' 和 'vertical-align' 属性