基本概念
概述
视觉格式化模型:用户代理
User Agent
如何在视觉媒体Visual Media
下处理文档树Document Tree
。视觉格式化模型会根据CSS盒子模型将文档中的元素转换为一个个盒子,每个盒子的布局由以下因素决定:
盒子的尺寸:精确指定、由约束条件指定或没有指定
盒子的类型:行内盒子(inline)、行内级盒子(inline-level)、原子行内级盒子(atomic inline-level)、块盒子(block)
定位方案(positioning scheme):普通流定位、浮动定位或绝对定位
文档树中的其它元素:即当前盒子的子元素或兄弟元素
视口尺寸与位置
所包含的图片的尺寸
其他的某些外部因素
视口 The Viewport
在连续媒体
Continuous Media
上工作的用户代理一般会向用户提供一个视口(屏幕上的一个窗口或其它可视区域)来帮助用户访问文档。用户代理可以在调整视口大小的同时改变文档的布局(见初始包含块Initial Containing Block
)。如果视口小于渲染文档的画布区域,用户代理应提供一个滚动机制。每个画布最多有一个视口,但用户代理可以把文档渲染到多个画布上(即为相同文档提供不同视图)。
包含块 Containing Blocks
CSS2.1中,许多盒的定位和大小都根据一个名为包含块
Containing Block
的矩形盒的边缘来计算。一般地:
生成的盒会充当其后代盒的包含块;
我们称盒为其后代“创建”了包含块。
说“盒的包含块”即是说“盒所处的包含块”,而不是盒所产生的包含块。
每个盒会被赋予一个相对于其包含块的位置,但它不会被局限在其包含块内;它有可能溢出。
包含块的尺寸如何计算的细节将在下章讲述。
“根元素”的包含块(初始包含块)由用户代理定义(浏览器)。在HTML中,根元素就是html元素,(部分浏览器根元素是body)。在大多数浏览器中,初始包含块是一个视窗大小的矩形(不等同于视窗,只是大小相等)
对于非根元素,如果position值是relative或者static,包含块则是最近的块级框。或者:表单元格或行内块祖先框的内容边界
对于非根元素,如果position值是absolute,包含块为最近的position值不是static的祖先元素(可以是任何类型)。具体过程如下:
如果这个祖先元素是块元素,包含块则设置为该元素的内边距边界;换句话说,就是由边框界定的区域
如果没有祖先元素,或者所有的祖先元素都没有开启定位,元素的包含块定义为初始包含块
对于定位的元素:只是包含块的边界与父元素的边框相同,但是因为left、top的默认值是auto,所以不影响padding对子元素的作用,设置了padding之后子元素并不会黏在父元素的边框上
可替换元素和不可替换元素
从元素本身的特点来讲,可以分为可替换元素(replaceable element)和不可替换元素(none-replaceable element)。
可替换元素
在 CSS中,可替换元素(replaced element)的展现效果不是由 CSS 来控制的。这些元素是一种外部对象,它们外观的渲染,是独立于 CSS 的。
简单来说,它们的内容不受当前文档的样式的影响。CSS 可以影响可替换元素的位置,但不会影响到可替换元素自身的内容。某些可替换元素,例如
可替换元素就是浏览器根据元素的标签和属性,来决定元素的具体显示内容。
CSS 能对可替换元素产生的唯一影响在于,部分属性支持控制元素内容在其框中的位置或定位方式
推论:
replaced element
之所以冠以replaced
的形容词,是因为这类element的内容会被指向的外部资源给replace掉,通过src
属性典型的可替换元素有:
有些元素仅在特定情况下被作为可替换元素处理,例如:
HTML 规范也说了 元素可替换,因为
"image"
类型的元素就像一样被替换。但是其他形式的控制元素,包括其他类型的元素,被明确地列为非可替换元素(non-replaced elements)。该规范用术语小挂件(Widgets)来描述它们默认的限定平台的渲染行为。
css 与 可替换元素
用 CSS
content
属性插入的对象是匿名的可替换元素。它们并不存在于 HTML 标记中,因此是“匿名的”。需要注意的是,一部分(并非全部)可替换元素,其本身具有的尺寸和基线(baseline)会被一些 CSS 属性用到,加入计算之中,例如
vertical-align
,会只有可替换元素才能具有这种自带值。
不可替换元素
html
的大多数元素是不可替换元素,即其内容直接表现给用户端(例如浏览器)。如果元素的内容包含在文档之中,则为非替换元素。除了几个可替换元素,其他所有的都是不可替换元素。
盒的生成 Controlling Box Generation
本节描述CSS2.1中可生成的盒类型。盒的类型会影响其在视觉格式化模型中的表现。
盒子的生成是 CSS 视觉格式化模型的一部分,用于从文档元素生成盒子。盒子有不同的类型,不同类型的盒子的格式化方法也有所不同。盒子的类型取决于 CSS
display
属性。
块级元素 Block-level Elements 和 块盒 Block Boxes
块 block:,一个抽象的概念,一个块在文档流上占据一个独立的区域,块与块之间在垂直方向上按照顺序依次堆叠。
元素 elements:是html的概念(与标签一一对应)
盒子 box:,一个抽象的概念,由CSS引擎根据文档中的内容所创建,主要用于文档元素的定位、布局和格式化等用途。盒子与元素并不是一一对应的,有时多个元素会合并生成一个盒子,有时一个元素会生成多个盒子(如匿名盒子)。
这些盒子与盒模型由对应关系吗?content-box? margin-box?
框:盒的边界,有些翻译用于指代盒子,如行内框,实指行内盒 inline box
块级元素 block-level element:
元素的
display
为block
、list-item
、table
时,该元素将成为块级元素。元素是否是块级元素仅是元素本身的属性,并不直接用于格式化上下文的创建或布局。
块级元素是文档中会被视觉格式化为块状(例:段落)的元素,默认按照垂直方向依次排列。
块级盒子 block-level box:
由块级元素生成。
参与块格式化上下文
Block Formatting Context
每个块级元素生成一个主要的块级盒
Principal Block-level Box
来包含其后代盒和生成的内容,同时参与定位体系Positioning Scheme
。某些块级元素还会在主要盒之外产生额外的盒:
list-item
元素。这些额外的盒会相对于主要盒来摆放,生成额外的盒子用于放置项目符号,而那些会生成列表项的元素可能会生成更多的盒子。不过,多数元素只生成一个主块级盒子。
块盒子 block box:
如果一个块级盒子同时也是一个块容器盒子(见下),则称其为块盒子。
除具名块盒子之外,还有一类块盒子是匿名的,称为匿名块盒子(Anonymous block box),匿名盒子无法被CSS选择符选中,当然,匿名块盒子也是块容器盒子和块级盒子
-
注意:盒子分为“块盒子”和“块级盒子”两种,但元素只有“块级元素”,而没有“块元素”。下面的“行内级元素”也是一样。
块容器盒子:
block container box或block containing box
除了表格盒
Table Boxes
,和可替换元素(Replaced Elements
),一个块级盒同时也是一个块容器盒Block Container Box
块容器盒子侧重于当前盒子作为“容器”的这一角色,它不参与当前块的布局和定位,它所描述的仅仅是当前盒子与其后代之间的关系。换句话说,块容器盒子主要用于确定其子元素的定位、布局等。
一个块容器盒子只会有两种情况:
只包含块级盒子
这看起来也许有些奇怪,这与上文提到的匿名块盒子有关,下文将会有详细的讲解
为什么没有提到 只包含块级盒子就创建一个块级格式化上下文呢?
只包含行内级盒子,创建一个行内格式化上下文
Inline Formatting Context
并非所有的块容器盒都是块级盒:
不可替换的行内块
Bon-replaced Inline Blocks
和不可替换的表格单元格Non-replaced Table Cells
也是块容器但不是块级盒。能够注意到块级盒子与块容器盒子是不同的这一点很重要。前者描述了元素与其父元素和兄弟元素之间的行为,而后者描述了元素跟其后代之间的行为。
这三个术语,“块级盒”、“块容器盒”、“块盒”在意义明确时可简称为“块”。
匿名块盒
在某些情况下进行视觉格式化时,需要添加一些增补性的盒子,这些盒子不能用CSS选择符选中,因此称为匿名盒子(
anonymous boxes)。CSS选择器不能作用于匿名盒子(
anonymous boxes),所以它不能被样式表赋予样式。也就是说,此时所有可继承的 CSS 属性值都为inherit
,而所有不可继承的 CSS 属性值都为initial
。
情况一
块容器盒子可能只包含行内级盒子,也可能只包含块级盒子,但通常的文档都会同时包含两者,在这种情况下,就会在相邻的行内级盒子外创建匿名块盒子。
- Some inline text复制代码
followed by a paragraph
followed by more inline text. 此时会产生两个匿名块盒子:一个是
元素前面的那些文本(
Some inline text
),另一个是元素后面的文本(
followed by more inline text.
)。此时会生成下面的块结构:显示为:
Some inline textfollowed by a paragraphfollowed by more inline text.复制代码
从情况一可知:
当一个块容器盒子,既包含行内级元素(生成行内级盒子),又包含块级元素(生成块级盒子)时,会创建匿名块盒子包裹行内级盒子,使得块容器盒子下只有块级盒子
情况二
另一种会创建匿名块盒子的情况是一个行内盒子中包含一或多个块盒子。此时,包含 块盒子 的行内盒子会拆分为两个行内盒子,分别位于块盒子的前面和后面。块盒子前面的所有行内盒子会被一个匿名块盒子包裹,块盒子后面的行内盒子也是一样。因此,块盒子将成为这两个匿名块盒子的兄弟盒子。
如果有多个块盒子,而它们中间又没有行内元素,则会在这些盒子的前面和后面创建两个匿名块盒子。
请看下面的例子:
Some inline text followed by a paragraph followed by more inline text.
复制代码此时会产生两个匿名块盒子:一个是
元素前面的文本(
Some *inline* text
),另一个是其之后的文本(followed by more inline text.
)。此时会生成下面的块结构:
从情况二可知:
即使在html结构上使用行内级元素包裹块级元素,在渲染的时候也依然是块级盒子包裹行内级盒子,这是可以使用行内及元素包裹块级元素的真正原因
注意:
对匿名盒子来说,程序员无法像
元素那样控制它们的样式,因此它们会从包含它的非匿名盒那里继承那些可继承的属性,如
color
。其他不可继承的属性则会设置为initial
,比如,因为没有为它们指定background-color
,因此其具有默认的透明背景,而元素的盒子则能够用CSS指定背景颜色。类似地,两个匿名盒子的文本颜色总是一样的。
当一个元素导致了匿名块盒的生成,则该元素上设置的属性一样能应用于该元素生成的盒和该元素的内容。例如,在上面例子中,如果在
p
元素上设置了边框,则这个边框将画在C1
(在行的结尾开)和C2
(在行的结尾闭)周围。p{ display:inline; border:solid red; /*不可继承*/ background:yellow; /*不可继承*/ color:red; /*可继承*/ } span{ display:block;}复制代码
计算百分比值时,应忽略匿名块盒,而以最近的非匿名祖先盒来替代。例如,情况一的
div
里,如果一个匿名块盒的子盒在需要知道其包含块的高度来获得一个百分比高度。那么它将使用div
形成的包含块的高度,而不是匿名块盒的高度。
行内级元素 Inline-level Elements 和 行内盒 Inline Boxes
行内级元素 Inline-level Element:
是在源文档中那些不为其内容形成新的块、其内容分布在多行中的元素(如,段落内着重文本,行内图片等等)。
与块级元素一样,元素是否是行内级元素仅是元素本身的属性,并不直接用于格式化上下文的创建或布局。
以下的
display
属性值产生一个行内级元素:inline
,inline-table
,以及inline-block
。
行内级盒 Inline-level Boxes :
行内级元素生成行内级盒
Inline-level Boxes
,行内级盒子包括行内盒子和原子行内级盒子两种,区别在于该盒子是否参与行内格式化上下文的创建。
行内盒 Inline Boxes:
行内盒是一个行内级盒,且其内容参与了该行内盒的行内格式化上下文。
一个
display
值是inline
的不可替换元素会生成一个行内盒。与块盒类似,行内盒也分为具名行内盒和匿名行内盒(anonymous inline box)两种。
原子行内级盒 Atomic Inline-level Boxes :@
那些不是行内盒的行内级盒(例如可替换的行内级元素
Replaced Inline-level Elements
、行内块元素inline-block
、行内表格元素inline-table
)被称为原子行内级盒Atomic Inline-level Boxes
,因为它们以单一不透明盒的形式来参与它们的行内格式化上下文。原子行内级盒子一开始叫做原子行内盒子(atomic inline box),后被修正。
原子行内级盒子的内容不会拆分成多行显示。
匿名行内盒 Anonymous Inline Boxes
任何被直接包含在一个块容器元素(不是包含在行内元素)的文本必须作为匿名行内元素来对待。
如下:
Some emphasized text
复制代码p
产生一个块盒,其中包含了一些行内盒。emphasized
的盒是一个由行内元素em
生成的行内盒,但其他盒(some
和text
的)是由块级元素p
生成的行内盒。后面这种盒被称作匿名行内盒,因为它们没有相关的行内级元素。这些匿名行内盒的可继承属性将从它们的父级块盒中继承。非继承性属性取其初始值。在上面例子中,匿名行内盒的
color
从p
那里继承,但background
为transparent
。空白内容,根据
white-space
属性,如果可被折叠则不会产生任何匿名行内盒。本规范中,如果可根据上下文来清晰界定一个匿名盒的类型,则匿名行内盒和匿名块盒都可被简称为匿名盒。
在格式化表格时,还会有更多类型的匿名盒出现。
Run-in Boxed 插入盒
为使章节号同之前的草案一致,特保留此节。
display: run-in
现已定义至CSS3(参见CSS基本盒模型)。