Containing Block[包含块]
原作:
hanlray@gmail.com
再整理:豆豆猫
注:
1)在《css权威指南中文版》中Containing Block翻译为包含块,在此沿用此译法为了可以让译文看着更通顺一些,中英夹杂的文章毕竟阅读有些困难,不过有些属性值不做翻译。
2)属性:property
3)元素/对象:element
4)block:块级(不翻译)
5)inline:内联/行内(不做翻译)
6)box:盒子,参考:box model 盒模型
http://www.ddcat.net/blog/archives/2007/02/138.html
7)formatting context:这个拿不准,格式化范围?上下文格式化?
8)根:root
8)W3C CSS2.1中关于Containing Block的说明:
http://www.w3.org/TR/CSS21/visuren.html#containing-block
----------------------X 正文开始 X----------------------
稍微复习一下CSS的视觉格式化模型(Visual Formatting Model,就是CSS怎么展示html的模型):
·display属性控制着box的产生,none值不产生box,block等值使元素产生一个block box,inline等值使元素产生一个或多个inline box;
·正常的流程里的每个box都参与一个格式化范围(formatting context),具有相同包含块的boxes参与同一个格式化范围,
block boxes参与block格式化范围,
inline boxes参与inline 格式化范围;
·在一个block格式化范围里,boxes(block boxes)从包含块的顶部开始,一个接一个垂直排列;
在一个inline格式化范围里,boxes(inline boxes)从包含块的顶部开始,一个接一个水平排列。
一个元素的包含块是该元素产生的box(es)在计算位置和大小时参考的一个矩形。通常在一个(x)html文档中,大多数元素的包含块都由一个block box来担当,为该block box的内容区域(content area),因此我们常直接说这些元素的包含块是某个blockbox,实际指的是该block box的内容区域。
不过并不是所有元素的包含块都是由一个包含块来担当的,比如根元素的包含块,对连续媒体(ContinuousMedia)来说是锚点(anchor)在画布(canvas)的原点、大小是视口(viewport)大小的矩形,对pagemedia来说是page box的page area,大小也是视口的大小。
一个block box为其后代(descendant)boxes建立了一个包含块,对其正常流(normal flow)里的boxes建立了一个格式化范围,该包含块包含的boxes按照这个格式化范围的规则进行布局。
如果把一个元素的包含块简单地理解为该元素的父(parent)元素产生的box,在某些情况下你将无法解释浏览器的布局行为,下面是CSS 2.1 Specification上的一个例子:
复制内容到剪贴板
代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
<title></title>
<style type="text/css">
body {
display: inline;
}
</style>
</head>
<body>
This is anonymous text before the p.
<p>This is the content of p.</p>
This is anonymous text after the p.
</body>
</html> 这里用CSS把<body>变成了一个inline元素,但<p>仍然是一个block元素,这样<body>就被<p>打断而产生两个inline box,分别对应第一句话和第三句话,这时<p>产生的blockbox应该以哪个矩形为参考进行放置呢?无论选择第一个inline box或第二个inline box,还是由这两个inlinebox计算出的矩形,都无法解释其在一个符合CSS2.1的浏览器上的表现。
事实上,这里<p>的包含块由<html>产生的block box来担当的,其产生的block box应该以<html>产生的blockbox的内容区域为参考进行放置,因为CSS2.1是这么说的:对根元素以外的元素,如果该元素的position(定位)为relative(相对)或static(静态),其包含块是离该元素最近的block-level或tablecell或inline-block的祖先(ancestor)box的内容区域。
有了这个认识,再来解释这段代码在浏览器上的表现:<p>的包含块是<html>产生的block box,因此紧挨页面的左边缘,body产生的两个inlinebox的包含块也是html的box,但是由于一个包含(containing)box只能包含一种box,要么全是blockboxes,要么全是inline boxes,因此会产生两个匿名block box,分别包着这两个inlineboxes,这样这三个blockbox都参与到一个块格式化范围中,从包含box的顶部,按照文档中出现的次序,从上到下垂直排列;由于在html的默认样式表里,<body>的margin值为8pt,这个margin应用到两个inlinebox上,从而使第一句话和第三句话离页面左边缘有了一段8pt的距离。
在默认样式表下,试图仅仅通过把一个block元素变成inline元素来把该元素的box(es)放置在其上一个元素的box的右边,必须满足两个条件:
1.和该元素属于同一个包含块的元素必须都是inline级的,否则inline元素产生的inline box(es)都将被包在一个匿名block box里,从而垂直排列
2.该元素的子孙元素也必须是inline-level的,原因上面已经解释过了。