在css中,一切都是框。div、h1 或 p 元素常常被称为块级元素,意味着这些元素显示为一块内容,呈现出的是一个个块框。与之相反,span 和 strong 等元素称为行内元素,这是因为它们的内容会被显示在一行中,呈现出的是一个个行内框。可视化格式模型解释的就是,怎样把这些框,按照一定规则摆放在页面上。
1. 控制框
(1) 块级元素和块框
块级元素是源文档中那些在视觉上被格式化为块(如:段落)的元素。块元素会生成块框,块框里面包含有内容和该块的子元素,同时块框参与到块格式化上下文的定位中(具体见CSS定位之常规流一文)。除了表格框及替换元素(如<img>,元素的内容会由其url指定的图片所替换),块框同时也是一个块包含框。一个块包含框中要么只包含块级框,要么创建出一个行内格式化上下文(具体见CSS定位之常规流一文)。如果其中既有块元素又有行内元素,那么会默认生成匿名的块框来达到这一要求,下面有具体例子说明。
但是,并不是所有块包含框都是块框,像是inline-block元素也生成了一个块包含框,但它并不是一个块框,它参与的是行内格式化上下文中。
除了一些明确的块级元素div、p等,某些display属性的取值也会产生块框:
- block:该值使一个元素生成一个块框。
- list-item:该值使一个元素(如HTML中的LI)生成一个原始块框和一个列表项行内框。
- table:使一个元素表现为类似一个表格元素.
匿名块框是指,当一个块框里包含另一个块框时,我们强迫这个块框里头只包含块框或插入框,所以任何行内框都会被包含在一个匿名块框内,以达到这一目的。
css specification中的例子如下,
<DIV>
Some text
<P>More text
</DIV>

div元素中既有行内元素又有块元素,那么在行内元素上就会有一个匿名的块框。
(2)行内元素和行内框
行内元素(a、em、strong等)会生成行内框。某些display属性的取值也会形成行内框:
- inline : 该值使一个元素生成一个或多个行内框。
- inline-block:该值使一个元素生成一个块框,但其自身在文档流中像一个行内元素,跟替换元素相似。元素的内部按照块框布局,自身按照一个行内替换元素格布局。
- inline-table : 使一个元素表现为类似一个表格元素
匿名行内框是指一个块级元素产生的、与任何行内元素无关的行内框。
css specification中的例子如下,
<P>Some <EM>emphasized</em> text</P>
p元素生成一个块控制框,其内还有几个行内框。"emphasized"的框是一个行内元素(<em>)产生的行内框,而其它的框("Some"和"text")是块级元素(P)产生的行内框。后者就称为匿名行内控制框。
这样的行内框从其父块框那里继承可以继承的属性。非继承属性取它们的初始值。
2. 包含块
一个元素的定位和尺寸计算,有时候会跟某一矩形框有关,即该元素的包含块。包含块的定义如下:
- 根元素存在的包含块,成为初始包含块 (initial containing block)。
- position:static和position:relative定位的元素,包含块是离它最近的块级祖先元素的内容框(padding内的框)。
- position:fixed定位的元素,包含块是当前可视窗口。
- position:absolute定位的元素,包含块由离它最近的 position 属性为 “absolute”、“relative” 或者 “fixed” 的祖先元素创建:
- 如果该祖先元素是一个行内元素,且其direction:ltr,则包含块的顶、左边是祖先元素中第一个行内框的顶、左边界 ,右、下边是祖先元素中最后一个行内框的右、下边界 。
- 如果该祖先元素是一个行内元素,且其direction:rtl,则包含块的顶、右边是祖先元素中第一个行内框的顶、右边界 ,左、下边是祖先元素中最后一个行内框的左、下边界 。
<html>
<head>
<style type="text/css">
p {font-size:20px;width:200px; padding:20px;line-height:50px;}
span {background-color:#C0C0C0; position:relative;}
em#lt {position:absolute; color:red; top:0; left:0;}
em#rt {position:absolute; color:yellow; top:0; right:0;}
em#lb {position:absolute; color:blue; bottom:0; left:0;}
em#rb {position:absolute; color:green; bottom:0; right:0;}
</style>
</head>
<body>
<p>
T
<span>
这段文字从左向右排列,红 X 和 蓝 X 和黄 X 蓝 X 都是绝对定位元素,用来判断它们包含块的边缘。
<em id='lt'>X</em>
<em id='rt'>X</em>
<em id='lb'>X</em>
<em id='rb'>X</em>
</span>
</p>
</body>
</html>
行内元素内形成的包含块,在各浏览器中各不相同,存在兼容性问题。
上述例子在firefox中的效果:
在chrome中的效果:
- 其他情况下,如果祖先元素不是行内元素,那么包含块的区域应该是祖先元素的内边距边padding edge(注意与第二条中中内容区content edge的区别)。
<html>
<head>
<style type="text/css">
div#container {margin:10px; padding:10px; border:1px solid; background-color:#c0c0c0; position:relative; width:200px; height:100px;}
div#content{border:1px solid red; position:absolute; left:0; top:0;}
</style>
</head>
<body>
<div id='container'>
<div id='content'>absolute element</div>
</div>
</body>
</html>
3. 定位方案
css可视化格式模型中共有三种定位方案,分别是:常规流定位、浮动和绝对定位。后面的文章将分别介绍这三种定位方案。