视觉格式化模型 Visual Formatting Model
URL:http://www.w3.org/TR/CSS2/visuren.html Translator: HaoyCn Date: 10th of Aug, 2015
本文并未全部翻译,译者在原文基础上稍有添加图示。如了解全部信息,请参看规范原版。个人水平有限,欢迎指正。
9.1 视觉格式化模型介绍
本章和下章用于描述视觉格式化模型:用户代理 User Agent如何在视觉媒体 Visual Media 下处理文档树 Document Tree。
视觉格式化模型中,文档树中的每一个元素根据盒模型 Box Model 产生零个或多个盒。这些盒的布局由以下内容控制:
盒的尺寸和类型
定位体系 Positioning Scheme(常规流,浮动和绝对定位)
立即学习“前端免费学习笔记(深入)”;
文档树中元素之间的关系
外部信息(如:视口大小,图片的固有尺寸等)
本章及下章定义的属性适用于连续媒体和页面媒体 Paged Media。然而,外边距属性的意义在页面媒体中有所不同(详情见页面模型)。
视觉格式化模型没有指定格式化的所有方面(如,没有指定字符间距算法)。本规范没有覆盖到的格式化问题上,符合规范的用户代理也可能表现不一。
9.1.1 视口 The Viewport
在连续媒体 Continuous Media 上工作的用户代理一般会向用户提供一个视口(屏幕上的一个窗口或其它可视区域)来帮助用户访问文档。用户代理可以在调整视口大小的同时改变文档的布局(见初始包含块 Initial Containing Block)。
如果视口小于渲染文档的画布区域,用户代理应提供一个滚动机制。每个画布最多有一个视口,但用户代理可以把文档渲染到多个画布上(即为相同文档提供不同视图)。
9.1.2 包含块 Containing Blocks
CSS2.1中,许多盒的定位和大小都根据一个名为包含块 Containing Block 的矩形盒的边缘来计算。一般地,生成的盒会充当其后代盒的包含块;我们称盒为其后代“创建”了包含块。说“盒的包含块”即是说“盒所处的包含块”,而不是盒所产生的包含块。
每个盒会被赋予一个相对于其包含块的位置,但它不会被局限在其包含块内;它有可能溢出。
包含块的尺寸如何计算的细节将在下章讲述。
9.2 盒的生成 Controlling Box Generation
本节描述CSS2.1中可生成的盒类型。盒的类型会影响其在视觉格式化模型中的表现。下面描述的 display 属性用来指定盒的类型。
9.2.1 块级元素 Block-level Elements 和 块盒 Block Boxes
块级元素是源文档中会被视觉格式化为块状(例:段落)的元素。display 属性的以下值会让一个元素成为块级元素:block、list-item以及table。
块级盒Block-level Boxes是参与块格式化上下文 Block Formatting Context 的盒。每个块级元素生成一个主要的块级盒 Principal Block-level Box 来包含其后代盒和生成的内容,同时参与定位体系 Positioning Scheme。某些块级元素还会在主要盒之外产生额外的盒:list-item 元素。这些额外的盒会相对于主要盒来摆放。
除了(下章要讲的)表格盒 Table Boxes,和可替换元素(Replaced Elements),一个块级盒同时也是一个块容器盒 Block Container Box,一个块容器盒要么只包含块级盒,要么创建一个行内格式化上下文 Inline Formatting Context 并只包含行内级盒 Inline-level Boxes。并非所有的块容器盒都是块级盒:不可替换的行内块 Bon-replaced Inline Blocks 和不可替换的表格单元格 Non-replaced Table Cells 也是块容器但不是块级盒。是块级盒、同时也是块容器的盒称作块盒 Block Boxes。
这三个术语,“块级盒”、“块容器盒”、“块盒”在意义明确时可简称为“块”。
9.2.1.1 匿名块盒
在一个如下文档中:
Some text
More text
(假定 div 和 p 都设置了 display: block,)div 看起来似乎同时包含了行内类型的内容和块类型的内容。为了使界定格式化简单一些,我们假定有一个匿名块盒 Anonymous Block Box 围绕在“Some text”周围。
该例如图所示,有三个盒,其中一个为匿名盒。
换句话说:如果一个块容器盒(如上例中为 div 生成的盒)内有一个块级盒(如上例中的 p),那么我们强制它只包含块级盒。
当一个行内盒 inline box 包含一个文档流内 In-flow 的块级盒,这个行内盒(及在同一行盒的 Line Box 它的行内祖先)会在该块级盒(及其连续的或者中间只被可折叠空白、脱离文档流元素分隔的块级同胞)的周围打断,把行内盒分离成两个盒(甚至一边为空也如此),各在块级盒一边。在打断之前和打断之后的行盒 Line Box 都被匿名块盒包含,并且该块级盒成为匿名块盒的同胞。当这样的行内盒受到相对定位影响,任何产生的移动同样影响到包含在其中的块级盒。
该模型将应用在下面的例子中。假设有规则如下:
{ display: inline }
span { display: block }
被应用到如下HTML文档:
This is anonymous text before the SPAN。
This is the content of SPAN.
This is anonymous text after the SPAN。
p 元素包含一段匿名文本 C1,接着是一个块级元素,随后又是另一段匿名文本 C2。结果生成了一个代表 body 的块盒,它包含了围绕 C1 一个匿名块盒、span 的块盒,和围绕 C2 的另一个匿名块盒。
匿名盒的继承属性会从包含它的非匿名盒那里继承(比如,在子节标题“匿名块盒”下的那个例子中的 div 盒)。匿名盒的非继承属性将取其初始值。例如,匿名盒的字体属性继承自 div,但是外边距是 0。
当一个元素导致了匿名块盒的生成,则该元素上设置的属性一样能应用于该元素生成的盒和该元素的内容。例如,在上面例子中,如果在 p 元素上设置了边框,则这个边框将画在 C1(在行的结尾开)和 C2(在行的结尾闭)周围。
一些用户代理用其它方式实现了行内包含块 Inlines Containing Blocks 上的边框。例如,将其内嵌的块放入“匿名行盒”中,并在这些匿名行盒周围绘出行内边框。由于CSS1和CSS2没有定义这种表现,仅支持CSS1或CSS2的用户代理才会以其它形式来实现,并仍声称遵守这部分CSS2.1规范。对于CSS2.1规范发布之后的用户代理不会这么做。
IE6下的效果:
计算百分比值时,应忽略匿名块盒,而以最近的非匿名祖先盒来替代。例如,上面的 div 里,如果一个匿名块盒的子盒在需要知道其包含块的高度来获得一个百分比高度。那么它将使用 div 形成的包含块的高度,而不是匿名块盒的高度。
9.2.2 行内级元素 Inline-level Elements 和 行内盒 Inline Boxes
行内级元素是在源文档中那些不为其内容形成新的块、其内容分布在多行中的元素(如,段落内着重文本,行内图片等等)。以下的 display 属性值产生一个行内级元素:inline,inline-table,以及 inline-block。行内级元素生成行内级盒 Inline-level Boxes,而这些盒会参与行内格式化上下文 Inline Formatting Context。
一个行内盒是行内级盒,且其内容参与了该行内盒的行内格式化上下文。一个 display 值是 inline 的不可替换元素会生成一个行内盒。那些不是行内盒的行内级盒(例如可替换的行内级元素 Replaced Inline-level Elements、行内块元素 inline-block、行内表格元素 inline-table)被称为原子行内级盒 Atomic Inline-level Boxes,因为它们以单一不透明盒的形式来参与它们的行内格式化上下文。
9.2.2.1 匿名行内盒 Anonymous Inline Boxes
任何被直接包含在一个块容器元素(不是包含在行内元素)的文本必须作为匿名行内元素来对待。
一个HTML文档如下:
Some emphasized text
p 产生一个块盒,其中包含了一些行内盒。emphasized 的盒是一个由行内元素 em 生成的行内盒,但其他盒(some 和 text 的)是由块级元素 p 生成的行内盒。后面这种盒被称作匿名行内盒,因为它们没有相关的行内级元素。
这些匿名行内盒的可继承属性将从它们的父级块盒中继承。非继承性属性取其初始值。在上面例子中,匿名行内盒的 color 从 p 那里继承,但 background 为 transparent。
空白内容,根据 white-space 属性,如果可被折叠则不会产生任何匿名行内盒。
本规范中,如果可根据上下文来清晰界定一个匿名盒的类型,则匿名行内盒和匿名块盒都可被简称为匿名盒。
在格式化表格时,还会有更多类型的匿名盒出现。
9.2.3 Run-in Boxed 插入盒
为使章节号同之前的草案一致,特保留此节。display: run-in现已定义至CSS3(参见《CSS基本盒模型》)。
9.2.4 display 属性
(译者注:本处暂只记录常见几个值的简略介绍)
block 元素产生一个块盒。
inline-block 元素产生一个行内级块容器。行内块的内部会被当作块盒来格式化,而此元素本身会被当作原子行内级盒来格式化。
inline 元素产生一个或多个的行内框。
none 元素不出现在格式化结构中(也就是说,在视觉媒体中元素既不产生盒也不影响布局)。其后代元素也不产生任何盒:该元素及其内容会被从格式化结构中完全移除。对后代元素设定 display 属性不能覆盖这个表现。
请注意 none 值不产生可见盒;它根本就不生成盒。CSS中有使元素在格式化结构中产生盒并影响格式化,但盒本身不可见的机制。请访问visibility的章节了解详情。
除定位元素和浮动元素以及根元素外(见下文)计算值与指定值相同。根元素的计算值按下文所述改变。
注意,尽管 display 初始值是 inline,但用户代理的默认样式表规则可能覆盖该值。请见附录中的HTML4参考样式表。
9.3 定位体系 Positioning Schemes
在CSS2.1中,盒子根据以下三种体系来布局:
常规流 Normal Flow。CSS2.1中,常规流包括块级盒的块格式化,行内盒的行内格式化,以及块级盒和行内级盒的相对定位。
浮动 Floats。在浮动模型中,盒首先根据常规流布局,然后从常规流中脱离并尽可能地向左或向右位移。内容可以布局在浮动周围。
绝对定位 Absolutr Positioning。在绝对定位模型中,盒完全从常规流中脱离(对后面的同胞元素无影响)并根据包含块来分配位置。
浮动元素、绝对定位元素、根元素都被称为脱离文档流 Out of Flow;其他元素被称为文档流内 In-flow。元素 A 的排版流由 A、在文档流内且最近的脱离文档流的祖先是A的元素构成。
9.3.1 选择定位体系:position 属性
(译者注:本节翻译有省略)
static:盒为常规盒,根据常规流布局,top、right、bottom、left 属性不生效。
relative:盒的定位根据常规流计算(盒被成为常规流内定位)。接着盒相对其常规位置移动。当B盒相对定位,B盒之后的盒定位时就当B没有移动一样来计算。table-row-group、table-header-group、table-footer-group、table-row、table-column-group、table-column、table-cell以及table-caption 上次未定义此效果。
absolute:盒的位置(还可能包括大小)由 top、right、bottom、left 属性指定。这些属性根据盒的包含块来规定移动。绝对定位盒脱离文档流。这意味着它们对之后的同胞盒的布局没有影响。同时,即便绝对定位盒有外边距,也不同其他任何外边距折叠。
fixed:盒的定位根据 absolute 模型来计算,但除此之外,盒相对某些参照物保持固定。和 absolute 模型一样,此盒的外边距也不同其他任何外边距折叠。在手持 handheld、投影 projection、屏幕 screen、打字机 tty、电视 tv 媒体类型中,盒相对视口固定且滚动时不会移动。在打印媒体类型中,即便页面是通过视口来访问的(比如打印预览),盒也渲染在所有页,并且根据页盒固定。其他媒体类型中则未定义此表现。开发者可根据依赖媒体来指定 fixed。比如说,如果想使盒固定在屏幕视口顶部,但不出现在打印页的顶部,这两种设定可以通过使用@media规则来分开,如下:
@media screen {
h1#first { position: fixed }
}
media print {
h1#first { position: static }
}
用户代理不可将固定盒的内容分页显示。注意用户代理可能用其他方法打印不可见内容。参见第13章“页盒外的内容”。
用户代理可将根元素上的 position 视为 static。
9.3.2 盒位移 Box Offsets:top,right,bottom,left
(译者注:本节暂略,可参考CSS手册)
9.4 常规流 Normal Flow
常规流中的盒子都属于某个格式化上下文,要么块格式化上下文,要么行内格式化上下文,总之不能二者得兼。块级盒参与块格式化上下文,行内级盒参与行内格式化上下文。
9.4.1 块格式化上下文
浮动、绝对定位元素、非块盒的块容器(如:行内块inline-block、表格单元格 table-cell以及表格标题table-caption)以及 overflow 属性不为 visible 的块盒(除了该值被传播到视口的情况)将为其内容创建一个新的块级格式化上下文。
在块格式化上下文中,盒从包含块顶部一个接一个地垂直摆放。两个同胞盒间的垂直距离取决于 margin 属性。同一个块格式化上下文中的相邻块级盒的垂直外边距将折叠。
在块格式化上下文中,每个盒的左外边缘紧贴包含块的左边缘(从右到左的格式里,则为盒右外边缘紧贴包含块右边缘),甚至有浮动也是如此(尽管盒里的行盒可能由于浮动而收缩),除非盒创建了一个新的块格式化上下文(在这种情况下盒子本身可能由于浮动而变窄)。
关于在页面媒体 Paged Media 中分页的信息,请参考允许页面分页的章节。
9.4.2 行内格式化上下文
在行内格式化上下文中,盒从包含块的顶部一个接一个地水平摆放。盒水平方向的外边距、边框和内边距在布局时都会考虑在内。盒的垂直对齐方式则不一:可能按底部或者顶部对齐,又或者按它们内容文本的基线对齐。包含了一行里所有盒的矩形区域被称为行盒 Line Box。
行盒的宽度取决于包含块以及浮动。行盒的高度取决于在行盒高度计算章节所给出的规则。
行盒的高总是足以容纳其包含的所有盒。然而,它可能高于其所包含的最高盒(比如,包含的盒以基线对齐)。当一个盒(B)的高度小于包含它的行盒的高度时,B的垂直对齐方式由 vertical-align 属性决定。当在水平方向上几个行内级盒不能完全被单个行盒包含时,它们会被分配到两个或者多个垂直摆放的行盒中。因此,一个段落就是多个行盒的垂直堆叠。行盒的堆叠没有垂直间距(除非有特别声明)并且从不重叠。
一般来说,行盒的左边缘紧贴其包含块的左边缘,其右边缘紧贴包含块的右边缘。然而,浮动盒可能被置于包含块和行盒边缘之间。因此,尽管在同一行内格式化上下文中的行盒是等宽的(包含块的宽度),由于浮动会造成可用的水平空间减少,行盒的宽度仍可能变动。同一行内格式化上下文中的行盒在高度上通常是变动的(比如,一行可能包含图片但其他行仅包含文本)。
当一行中的行内级盒的总宽度小于包含它们的包含块的时候,它们在行里的水平分布取决于 text-align 属性。如果取 justify 值,用户代理可能拉伸行内盒(inline-table和inline-block盒除外)中的空格和字间距。
当行内盒的宽度超过行盒宽度时,行内盒将被分为多个盒,被分解出的盒则又分布在多个行盒中。如果一个行内盒不可切割(比如,行内盒包含的是单个字符或者语言指定的断字规则不允许断字,又或者行内盒的 white-space 属性值为 nowrap 或 pre),那么该行内盒将溢出行盒。
当行内盒被分割,外边距、边框和内边距在任何断点处都不会产生视觉影响。
行内盒也可能由于双向文本处理而在一个行盒内被切割成多个盒。
为了包含行内格式化上下文中的行内级内容,行盒按需创建。有的行盒不包含文本、保留空白、外边距或内边距或边框不为零的行内元素、其他文档流内 In-flow 内容(如图片、行内块或行内表格),并且不以保留的换行符结尾,如果是为决定它们所包含的元素的定位,则必须视其为零高度的行盒,除此之外的其他目的下应视其为不存在。
下面是一个行内盒构造的例子。下属的段落(由HTML块级元素 p 创建)包含了有 em 和 strong 交叉的匿名文本。
Several emphasized words appear
in this sentence, dear.
p 元素生成了一个块盒来包含五个行内盒,其中三个行内盒是匿名的:
匿名:”Several”
em:”emphasized words”
匿名:”appear”
strong:”in this”
匿名:”sentence, dear.”
为了格式化该段落,客户端将五个行内盒放进行盒。在这个例子中,由 p 元素生成的盒创建了行盒的包含块。如果该包含块足够宽,所有的行内盒将放置在单个行盒:
Several emphasized words appear in this sentence, dear.
如果宽度不够,行内盒就会被分割并分布在多个行盒。段落可能就变成了:
Several emphasized words appear
in this sentence, dear.
或者:
Several emphasized
words appear in this
sentence, dear.
在最后这个情况里,em 盒被分割成了两个 em 盒(现称之为 split1 和 split2)。外边距、边框、内边距或者文本修饰在 split1 之前或者 split2 之后都没有视觉效果。
看下面这个例子:
Example of inline flow on several lines
登录后复制
EM {
padding: 2px;
margin: 1em;
border-width: medium;
border-style: dashed;
line-height: 2.4em;
}
Several emphasized words appear here.
根据 p 的宽度,这些盒可能分布如下:
外边距插在了 emphasized 之前和 words 之后
内边距被插在了 emphasized 之前、上、下,words值后、上、下。虚线边框渲染在了每个单词的三边。
9.4.3 相对定位 Relative Positioning
一旦一个盒遵循常规流或者浮动而布局好位置后,它有可能根据这个位置来相对位移。这被称作相对定位。通过这种方式移动盒(B1)对随后的盒(B2)没有影响:B2 被赋予了一个如同 B1 没有位移的位置,并且 B2 在 B1 移动后不会重定位。这意味着相对定位可能造成盒重叠。然而,如果相对定位造成一个 overflow:auto 或 overflow:scroll 的盒溢出,客户端必须通过创建滚动条来让用户可以访问到该内容(在其偏移位置),这可能影响布局。
一个相对定位盒保持其常规流中的大小,包括断行和原本为其保留的空间。包含块一节解释了相对定位盒创建新的包含块的情况。
对于相对定位元素而言,left 和 right 在不改变盒大小的同时使其水平位移。left 使盒向右移动,right 时期向左。 left 或 right 没有造成盒的分割或拉伸,因此应用的值始终满足:left = – right。
如果 left 和 right 值均为 auto(其默认值),应用的值为 0(即是说,盒保持在其原位)。
如果 left 是 auto,其应用值为 right 的负值(即盒向左移动 right值)。
如果 right 是 auto,其应用值为 left 的负值。
如果 left 和 right 均不为 auto,定位则被过度约束,其中一值必须被忽略。如果包含块的 direction 属性值为 ltr,则 left 值胜出而 right 值改为 -left。如果包含块的 direction 属性值为 rtl,right 值胜出而 left 值被忽略。
举例。下面三条样式规则是等效的。
div.a8 {
position: relative;
direction: ltr;
left: -1em;
right: auto
}
div.a8 {
position: relative;
direction: ltr;
left: auto;
right: 1em
}
div.a8 {
position: relative;
direction: ltr;
left: -1em;
right: 5em
}
top 和 bottom 属性在不改变相对定位元素的大小的同时使其上下位移。top 使其下移,bottom 则使其上移。 top 或 bottom 没有造成盒的分割或拉伸,因此应用的值始终满足:top = – bottom。如果二者均为 auto,其值则均为 0。如果其中一个值为 auto,则该属性取另一属性的负值。如果二者均不为 auto,bottom 将被忽略(也就是说,bottom 应用值为 top 的负值)。
注:在脚本环境中动态移动相对定位盒可以产生动画效果(见 visibility属性)。尽管相对定位可被用于上标和下标效果,但行高在自动调整时不会将其定位纳入计算。参见行高计算一节的描述了解更多信息。
相对定位的例子将在对比常规流、浮动和相对定位一节中提供。
9.5 浮动 Floats
在当前行中一个盒被移动到左侧或右侧称为浮动。浮动最有趣的特点是内容可以布局在其旁边(或者为 clear 属性所禁止)。内容会布局在左浮动盒的右侧,或布局在右浮动盒的左侧。下述内容是对浮动定位及内容布局的介绍。控制浮动行为的准则已经在float属性一节中描述。
浮动盒将被移动至左侧或右侧直至其外侧紧贴包含盒的边缘或另外一个浮动的外边缘。如果存在行盒,浮动盒的顶部外边缘将与行盒的顶部对齐。
如果水平方向没有足够的空间容纳浮动,它将下移直至能够放下它或者没有其他浮动。
由于浮动不在常规流中,在浮动之前或之后创建的非定位块盒将垂直摆放,如同浮动不存在一样。然而,当前行盒和随浮动后创建的行盒会按需缩短来为浮动的外边距盒腾出空间。
当有一个垂直定位满足以下全部四个条件时,行盒将紧挨着浮动:
在行盒顶部或之下
在行盒底部或之上
在浮动的上外边距边缘之下,并
在浮动下外边距边缘之上
注:这意味着总高度 Outer Height 为零或为负的浮动不会缩短行盒。
如果行盒被缩短到不能容纳任何内容,那么行盒将下移(其宽度会重新计算)直到可以容纳内容或不再有浮动。当前行中,任何在浮动盒之前的内容将移动到同一行中的浮动的另一侧重新布局。换句话说,如果行内级盒先于左浮动被放在行盒中,而行盒的剩余空间可以容纳左浮动,那么左浮动会被置于该行内,且与行盒顶部对齐,而已经放入该行盒的行内级盒会被相应地移动到浮动的右侧(右侧即是左浮动的另一侧),反过来对 rtl 和右浮动也是这样。
表格、块级可替换元素或者在常规流中创建新的块格式化上下文的元素(如 overflow 值非 visibile 的元素),它们的边框盒不可与它们同属一个块格式化上下文中的浮动元素的外边距盒重叠。如果有必要的话,应当通过把它们置于已出现的浮动的后面达到清除浮动的效果,但如果空间足够,可以将其放置在浮动旁边。但这可能使得该元素的框盒变得比10.3.3章节定义的还要窄。CSS2没有定义用户代理何时可以把元素置于浮动旁的情况,也没有定义元素会变得多窄的情况。
举例。在下面的文档片段中,包含块不足以容纳浮动旁边的内容,因此内容需要移动到浮动下面,并根据其 text-align 属性来在行盒中定位。
{
width: 10em;
border: solid aqua;
}
span {
float: left;
width: 5em;
height: 5em;
border: solid blue;
}
Supercalifragilisticexpialidocious
该片段可能如下图所示:
浮动可以并列,而这个模型也适用于同一行中的并列浮动元素。
下面的规则会使所有的 class=”icon” 的 img 盒浮动到左侧(并设左外边距为 0)。
img.icon {
float: left;
margin-left: 0;
}
考虑如下HTML代码和样式表:
img { float: left }
body, p, img { margin: 2em }
body { height: 8.5in }/ 计算百分百高度需要 /
#header {
position: fixed;
width: 100%;
height: 15%;
top: 0;
right: 0;
bottom: auto;
left: 0;
}
#sidebar {
position: fixed;
width: 10em;
height: auto;
top: 15%;
right: auto;
bottom: 100px;
left: 0;
}
#main {
position: fixed;
width: auto;
height: auto;
top: 15%;
right: 0;
bottom: 100px;
left: 10em;
}
#footer {
position: fixed;
width: 100%;
height: 100px;
top: auto;
right: 0;
bottom: 0;
left: 0;
}
…
…
…
…
9.7 display,position,float 之间的关系
三种属性均影响盒生成及布局,它们的交互如下:
如果 display 值为 none,那么 position 和 float 不会应用。这种情况下,元素不生成盒。
否则,如果 position 值为 absolute 或 fixed,盒为绝对定位,float 的计算值为 none,display 的设值如下表。盒的位置由 top、right、bottom 和 left 属性以及盒的包含块决定。
否则,如果 float 值不为 none,盒浮动且 display 的设值如下表。
否则,如果元素为根元素,display 设值如下表,除了其在CSS2.1中未定义 list-item 的指定值是否变为计算值 block 或 list-item。
否则,dislay 属性值使用指定值。
对应表:
指定值:inline-table
计算值:table
指定值:inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block
计算值:block
指定值:其他
计算值:同指定值
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。
发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/3104444.html