CSS2/visuren

From HTML5 Chinese Interest Group Wiki
Jump to: navigation, search

视觉格式化模型

内容概要

介绍

本章和下一章描述了视觉格式化模型:用户端在图形媒体下如何处理文档树

视觉格式化模型中,每一个文档树中的元素根据框模型产生零个或多个框。这些框的布局由下列内容控制:

本章和下一章中定义的属性适用于连续媒介页面媒介。不过外边距属性的含义在应用到页面媒介时会有些不同(详细内容请参见页面模型)。

视觉格式化模型并不指定格式化的所有方面(例如,它并不指定字符间距算法)。对于这个规范没有覆盖到的格式化问题,与CSS特性保持一致的用户代理也可能有不同的表现。

视口 Viewport

连续媒介上工作的用户代理通常会向用户提供一个视口(屏幕上的一个窗口或其它可视区域),用户可以通过它来访问文档。用户代理可以在视口被调整大小时改变文档的布局(详见初始包含块)。

如果视口小于渲染文档的画布区域,用户代理应当提供一个滚动机制。每个画布最多可拥有一个视口,但用户代理可以把文档渲染至多个画布上(即为相同文档提供不同的视图)。

包含块 Containing blocks

在CSS 2.1中,许多框的位置和大小都根据一个名为包含块的矩形框边缘来相对计算得到。为元素生成的框通常会充当其后裔框的包含块;我们称框为其后裔“创建”(establishes)了包含块。“框的包含块”表示“框所处的包含块”,而不是其产生的包含块。

每个框会被给予一个相对于其包含块的位置,但它不会被局限在其包含块内;它有可能会溢出

关于如何计算包含块尺寸的细节将在下一章描述。

框的生成 Controlling box generation

接下来的章节描述了CSS 2.1中可能产生的框的类型。在某种程度上,框的类型会影响其在视觉格式化模型中的表现。下面描述的“display”属性用来指定框的类型。

块级元素和块框 Block-level elements and block boxes

块级元素是源文件中会被格式化成块状(例:段落)的元素。'display'属性的以下取值会让一个元素成为块级元素:'block'、'list-item'、'table'。

块级框是参与块格式化上下文的框。每个块级元素生成一个主要的块级框来包含其子框和生成的内容,同时任何定位方案都会与这个主要的框有关。某些块级元素还会在主要框之外产生额外的框:例如“list-item”元素。这些额外的框会相对于主要框来放置。

除了table框,和可替换元素,一个块级框同时也是一个块容器框,一个块容器框要么只包含块级框,要么创建一个行格式化上下文而只包含行内级框。并非所有的块容器框都是块级框:不可替换的行内块和不可替换的table cell也是块容器但不是块级框。是块级框的块容器称作块框

三个术语:块级框(block-level box)、块容器框(block container box)和块框(block box)在意义明确的时候简称为块(block)。

Block box.jpg
匿名块框 Anonymous block boxes

有这样一个文档:

<DIV> Some text <P>More text </DIV>

(并假定DIV和P都设置了'display: block'),DIV似乎同时包含了行内类型的内容和块类型的内容。为了使格式化简单一些,我们假定有一个匿名块框围绕在"Some text"周围。

anon-block.png

换句话说:如果一个块容器框(如上例中为DIV生成的框)有一个块级框(如上例中的P),那么我们强制它只包含块级框在其中。

当一个行内框包含一个属于正常排版的块级框,这个行内框(及与其位于同一行框的行内祖先)会被从周围的块级框(及其连续的块级兄弟Note.png)中分离出来,把行内框分离成两个框,它在块级框两边。在打断之前和打断之后的行框都附入匿名块框,并且该块级框与匿名块框成为兄弟。当这样的行内框受到相对定位影响,任何产生的移动同样影响到包含在行内框内的块级框。

该模型将应用在下面的例子中,假设有规则如下:

p { display: inline } span { display: block }

被应用到如下HTML文档:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <HEAD> <TITLE>Anonymous text interrupted by a block</TITLE> </HEAD> <BODY> <P> This is anonymous text before the SPAN。 <SPAN>This is the content of SPAN.</SPAN> This is anonymous text after the SPAN。 </P> </BODY>

p元素包含一段匿名文本(C1),随后是一个块级元素,再随后是另一段匿名文本(C2)。对此生成了一个代表BODY的块框,它包含了围绕C1一个匿名块框、代表SPAN的块框,和围绕C2的另一个匿名块框。

匿名框的继承属性会从包含它的非匿名框那里继承。匿名框的非继承属性将取其初始值。例如,匿名框的字体属性继承自DIV,但是外边距是0。 当一个元素导致了匿名块框的生成,则该元素上设置的属性一样能应用于该元素生成的框和其内容之上。例如,在上面例子中,如果在P元素上设置了边框,则这个边框将画在C1(在最后一行下方开放)和C2(在第一行上方开放)周围。

一些用户代理用其它方式实现了行内包含块上的边框。例如,将其内嵌的块放入"匿名行框"中,并在这些匿名行框周围绘出行内边框。由于CSS1和CSS2没有定义这些效果,仅支持CSS1或CSS2的用户代理会以其它形式来实现,并可仍旧声称与CSS2.1的特征保持部分一致。对于CSS2.1规范发布之后才发布的用户代理,就不能再这么做了。

当处理百分比值时,应该忽略匿名块框,而以其最近的非匿名祖先框来替代。例如,如果一个匿名块框的孩子在DIV里面需要知道包含块的高度来解析一个百分比高度。那么它将使用DIV形成的包含块的高度,而不是匿名块框的高度。

Anony box.jpg

行内级元素和行内框 Inline-level elements and inline boxes

行内级元素是源文档中那些不为其内容形成新的块;而让其内容分布在多行中的元素(如,段落内着重的文本,行内图形等等)。以下的'display'属性值产生一个行内级元素:'inline', 'inline-table', and 'inline-block'。行内级元素生成行内级框,而这些框会参与某个行内格式化上下文。

一个行内框是行内级框,且其内容参与了包含它的行格式化上下文。一个'display'值是'inline'的非替换元素会生成一个行内框。那些不是行内框的行级框(例如可替换的行级元素、行内块元素Note.png、行内表格元素Note.png)被称为原子行内级框,因为它们是以单一不透明框Template:Extra not的形式来参与其行内格式化上下文。

Inline box.jpg
匿名行内框 Anonymous inline boxes

任何被直接包含在一个块容器元素(而不是行内元素)中的文本必须视为匿名行内元素

在如下的文档中:

<P>Some <EM>emphasized</em> text</P>

P元素生成一个块框,其内还有几个行内框。"emphasized"的框是由行内元素(EM)产生的一个行内框,而其它的框("Some"和"text")是块类元素(P)产生的行内框。后者就称为匿名行内框,因为它们没有与之相关的行内级元素。

这样的行内框从其父块框那里继承可以继承的属性。非继承属性取其初始值。例子中,匿名行内框的颜色继承自P,而背景是透明的。

空格内容,如果可被折叠(根据'white-space'属性),则其不会生成任何匿名行内框。

在本规范中,如果一个匿名框的类型可根据上下文来清晰界定,则匿名行内框和匿名块框都可被简称为匿名框。

在格式化表格时,还会出现更多类型的匿名框。

插入框

[本小节存在的目的是为了让章节号码与之前的草案一致。 'display: run-in;' 的定义已移至 CSS3(请参考 CSS 基本框模型)。]

'display' 属性

'display'

取值: block | list-item | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | none | inherit
初始: inline
適用於: 所有元素
繼承:
百分比: (不适用)
媒介: 全部
計算值: 见下文

本属性各取值的意义如下:

block

这个值让元素产生一个块框。

inline-block

这个值让元素产生一个行级块容器。行内块(inline-block)的内部会被当作块框来格式化,而此元素本身会被当作原子行级框来格式化。

inline

这个值让元素产生一个或多个的行内框。

list-item

这个值让元素(例:HTML 里的 LI)产生一个主块框与标记框。详情请看列表章节以获得与列表相关的资讯与列表排版的范例。

none

这个值让元素不出现在排版结构中(也就是在视觉媒体中,元素既不产生框也不影响布局)。其子孙元素也不产生任何框:该元素及其内容会被从排版结构中完全移除。对子孙元素设定 'display' 属性不能覆盖这个结果。
请注意display属性取值为 'none' 并不会产生隐形的框:'none' 完全不产生任何框。CSS 具有可以让元素在排版结构中出现并影响排版,但是框本身却不可见的属性。详情请看关于可见性的小节。

tableinline-tabletable-row-grouptable-columntable-column-grouptable-header-grouptable-footer-grouptable-rowtable-celltable-caption

这些值让元素产生表格元素的行为(受到表格章节描述的限制)。

除了定位元素、浮动元素(请参考「'display'、'position' 与 'float' 的关系 」)与根元素,本属性的计算值与指定值相同。根元素上的本属性计算值的变动会依照「'display'、'position' 与 'float' 的关系 」中描述的规则。

请注意,尽管 'display'初始值是 'inline',用户代理的预设样式表可能覆盖这个值。请参考附录的 HTML4 样本样式

这有几个 'display' 属性的例子: p { display: block } em { display: inline } li { display: list-item } img { display: none } /* 不显示图片 */

定位方案Positioning schemes

CSS 2.1 中,会根据三种定位方案来摆放框:

  1. 正常排版。CSS 2.1 中,正常排版包括对块级框的块格式化,对行级框的行格式化,对块级框和行级框的相对定位
  2. 浮动。在浮动模型中,一个框先按照正常排版来摆放,再将它从排版流中取出并尽可能地向左或向右偏移。其它内容可以排在一个浮动的周围。
  3. 绝对定位。在绝对定位模型中,一个框会从排版流中完全脱离出来(它对后续的兄弟没有影响),并相对其包含块来指定其位置。

如果一个元素是浮动、绝对定位或根元素,那么它被称为排版流之外(out of flow)的元素。如果一个元素不是排版流之外的元素,那么它被称为排版流之内(in-flow)的元素。元素A的排版流包括元素A以及这么一组元素:它们是排版流之内的元素,且它们在排版流之外最近的祖先是元素A。

Flow element.jpg
注:CSS 2.1 的定位方案可以实现网页作者期望的排版效果,而无需使用特殊的标记手段(例如:不可见的图片),这让文档具有更好的可读性。

选择定位方案 ― 'position' 属性

'position' 属性与 'float' 属性决定了要用 CSS 2.1 的哪种定位算法来计算一个框的位置。

'position'

取值: relative | absolute | fixed | inherit
初始: static
適用於: 所有元素
繼承:
百分比: (不适用)
媒介: 视觉
計算值: 同指定值

本属性各取值的意义如下:

static

元素生成的框是按正常排版方式来摆放的普通框。其'top''right''bottom''left' 属性不起作用。

relative

元素生成的框先按正常排版方式来计算其位置(这称作在正常排版下的位置),然后框相对于其正常位置进行偏移。若框 B 使用了相对定位,则会以假设框 B 还没有发生偏移之前的状态来计算其后面的框的位置。本规范未定义 'position: relative' 在table-row-group、table-header-group、table-footer-group、table-row、table-column-group、table-column、table-cell、and table-caption元素上的效果。

absolute

框的位置(可能包括大小)由 'top''right''bottom''left' 属性来指定。这些属性指定了框相对于其包含块的偏移量。绝对定位框会被排除在正常排版之外,这意味着它们对之后的兄弟框的布局没有影响。另外,虽然绝对定位框有外边距,这些外边距不与其他外边距折叠

fixed

框的位置按照 'absolute' 模型来计算,但是框相对于某个参考位置固定。如同 'absolute' 模型,框的外边距不与别的外边距折叠。若媒介型态是手持、投影、萤幕、打字机或是电视,则框相对于视口固定,而并不随着卷轴移动。若媒介型态是打印机,则框要渲染在每一页,并相对于页面框渲染,就算页面透过视口阅读(举例来说,预览列印的时候),也是这样。本规范未定义这个值在其他媒介型态上的呈现方式。网页作者可依媒介指定 'fixed' 值,举例来说,网页作者可能希望一个框维持在萤幕视口的上方,但又不在出现在印出来的每个页面的上方。这两种定位方案的设定可用 @media 规则分开,如同:
@media screen { h1#first { position: fixed } } @media print { h1#first { position: static } }
用户代理绝对不能将fixed框的内容分页显示。请注意用户代理可用别的方式来打印隐形的内容,详情请参考 13 章「页面框外面的内容」

用户代理可将根元素上的 'position' 视为 'static'。

框偏移 ― 'top''right''bottom''left'

本规范把 'position' 属性值不为 'static' 的元素称为定位元素。定位元素生成定位框,并根据以下四个属性来确定其摆放的位置:

'top'

取值: <length> | <percentage> | auto | inherit
初始: auto
適用於: 定位元素
繼承:
百分比: 相对于包含块的高度
媒介: 视觉
計算值: 若指定值为长度,计算值为对应的绝对长度。若指定值为百分比值,计算值同指定值。否则,为'auto'。

该属性可以用来指定绝对定位框的上外边距边从框包含块的顶边向下偏移的距离。若用在相对定位框上,偏移量相对于框自己的顶边(也就是,用户代理在正常排版下为框分派了一个位置,再从该位置按这些属性偏移)。

'right'

取值: <length> | <percentage> | auto | inherit
初始: auto
適用於: 定位元素
繼承:
百分比: 相对于包含块的宽度
媒介: 视觉
計算值: 若指定值为长度,计算值为对应的绝对长度。若指定值为百分比值,计算值同指定值。否则,为'auto'。

类似 'top',不过指定的是框的右外边距边从框包含块的右边向左偏移的程度。若用在相对定位框上,偏移量相对于框自己的右边。

'bottom'

取值: <length> | <percentage> | auto | inherit
初始: auto
適用於: 定位元素
繼承:
百分比: 相对于包含块的高度
媒介: 视觉
計算值: 若指定值为长度,计算值为对应的绝对长度。若指定值为百分比值,计算值同指定值。否则,为'auto'。

类似 'top',不过指定的是框的下外边距边从框包含块的底边向上偏移的程度。若用在相对定位框上,偏移量相对于框自己的底边。

'left'

取值: <length> | <percentage> | auto | inherit
初始: auto
適用於: 定位元素
繼承:
百分比: 相对于包含块的宽度
媒介: 视觉
計算值: 若指定值为长度,计算值为对应的绝对长度。若指定值为百分比值,计算值同指定值。否则,为'auto'。

类似 'top',不过指定的是框的左外边距边从框包含块的左边向右偏移的程度。若用在相对定位框上,偏移量相对于框自己的左边。

这四个属性的各种取值的意义如下:

<length>

偏移量是距离参考边的一个固定长度。允许取负值。

<percengage>

偏移量是包含块宽度('left''right')或高度( 'top''bottom' )的一个百分比。允许取负值。

auto

对于非替换元素,这个值的效果跟还有哪些相关属性的值也是 'auto' 相关,详情请参考说明绝对定位非替换元素宽度高度的小节。对于替换元素,这个值的效果只与替换内容的固有尺寸相关,详情请参考说明绝对定位替换元素宽度高度的小节。

正常排版Normal flow

框在正常排版中必然属于一个格式化上下文,要么是块格式化上下文,要么是行格式化上下文。块级框参与块格式化上下文行级框参与行格式化上下文

块格式化上下文 Block formatting contexts

有这几种框会为其内容创建新的块格式化上下文:浮动框、绝对定位框、非块框的块容器Note.png、'overflow'属性非'visible'的块框Note.png

在块格式化上下文中,框会从包含块的顶部开始,一个接一个地,垂直向下地摆放。两个兄弟框之间的垂直距离由 'margin' 属性来决定。在同一个块格式化上下文中,相邻的块级框之间的垂直外边距会出现折叠

在块格式化上下文中,每个框的左外边距边要紧贴其包含块的左边。即使在有浮动的情景下也是如此,除非框创建了一个新的块格式化上下文(在这种情况下该框可能会为了避开浮动框而变窄)。

关于在页面媒体中要如何分页,请参考允许页面分页的章节。

行格式化上下文 Inline formatting contexts

在行格式化上下文中,框会从包含块的顶部开始,一个接一个地水平摆放。摆放这些框的时候,它们在水平方向上的外边距、边框、内边距所占用的空间都会被考虑在内。在垂直方向上,这些框可能会以不同形式来对齐:它们可能会把底部或顶部对齐,也可能把其内部的文本基线对齐。能把在一行上的框都完全包含进去的一个矩形区域,被称为该行的行框

行框的宽度是由包含块和存在的浮动来决定。行框的高度由行高计算这一章所描述的规则来决定。

行框一定会高到足以容纳它所包含的全部框。然而,它也可能比它所包含的最高的框还要高(例如:这些框是以基线对齐)。当框B的高度小于包含它的行框时,则B在行框中垂直对齐的位置由 'vertical-align' 属性来决定。当几个行级框在水平方向上无法塞得进同一个行框时,它们会被分布在两个或多个垂直堆放的行框中。行框会以既没有垂直间距Note.png也没有重叠的方式被垂直堆放起来。

通常,行框的左边紧贴其包含块的左边,而行框的右边紧贴其包含块的右边。然而,浮动框可以插在包含块边缘与行框边缘之间。因此,尽管在同一个行内上下文中的行框通常有同样的宽度(也就是其包含块的宽度),但它们的宽度也可能受浮动让水平可用空间减少的影响而有所改变。在同一个行格式化上下文中,行框的高度通常是变化的(例如:某一行包含了一个比较高的图片,而其它行只包含文本)。

当一行上的行级框的总宽度小于包含它们的行框的宽度,则它们在行框内的水平分布由'text-align'属性来决定。如果该属性取值为'justify',则用户代理可拉伸行内框(但不能是inline-table和inline-block框)中的空格和字间距。

当一个行内框的宽度超过了行框的宽度,则它会被分割成几个框,而这些框会分布在几个行框。如果此行内框不可分割(例如:单个字符、或语言指定的文字打断规则不允许在此行内框中出现打断、或该行内框受white-space属性为nowrap或pre的影响),那么该行内框溢出该行框。

行内框被分割的时候,外边距、边框和内边距在出现分割的地方都没有视觉效果。

取决于双向文本处理,行内框也可能在同一个行框内被分割为几个框。

行框会被按需创建来包含行格式化上下文中的行级内容。如果行框不包含文本或保留空格,不包含内外边距或边框宽度非零的行内元素,也不包含其它正常排版的内容(比如images,inline blocks或inline tables),也不以保留的换行符结尾,像这样的行框,如果是为了决定在其中任意元素的定位,则必须以零高度的行框来对待,如果为了其它的一些目的,则必须以其不存在来对待。

这里有个关于构建行内框的实例。以下段落(由块级元素P创建)包含由元素EM和STRONG间隔的匿名文本:

<P>Several <EM>emphasized words</EM> appear <STRONG>in this</STRONG> sentence, dear.</P>

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之前的外边距、边框、内边距和文本修饰都没有视觉上的效果。

考虑下面这个例子:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> <HTML> <HEAD> <TITLE>Example of inline flow on several lines</TITLE> <STYLE type="text/css"> EM { padding: 2px; margin: 1em; border-width: medium; border-style: dashed; line-height: 2.4em; } </STYLE> </HEAD> <BODY> <P>Several <EM>emphasized words</EM> appear here.</P> </BODY> </HTML>

根据P的宽度,这些框可能分配如下:

inline-layout.png
  • 在"emphasized"之前和"words"之后插入了外边距。
  • 在"emphasized"之前、之上和之下,在"words"之后、之上和之下插入了内边距。在每个单词的三边渲染了虚线边框。

相对定位 Relative positioning

当一个框按照正常排版或浮动来摆放好之后,它就可能相对当时的位置再有所偏移,这被称作相对定位。以这种方式使一个框(B1)发生偏移,对跟随其后的框(B2)没有影响:B2的定位就好像B1还没有偏移,并且在B1应用了偏移后B2不进行重新定位。这意味着相对定位会导致框重叠。然而,如果相对定位导致 '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'(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'属性)。尽管相对定位也可用来产生上标和下标的效果,但自动调整行高时并不会将其占位考虑进去。见行高计算描述的更多信息。

相对定位的例子会在对比正常排版、浮动和绝对定位的章节中提供。

浮动 Floats

在当前行向左或右偏移的框就是浮动框。浮动框最有趣的特点是其它内容可以紧挨着它的一侧来排版 (也可以通过'clear'属性来禁止这样排版)。内容会紧挨着左浮框的右侧排版,而紧挨着右浮框的左侧排版。接下来是对浮动定位和内容流的介绍。控制浮动行为的准确规则会在'float'属性的描述中提供。

一个浮动框会向左或向右进行偏移直到其外边缘紧贴其包含块的边缘或另一个浮动框的外边缘。如果摆放浮动框时,当前行已有一个行框,则浮动框的顶部外边缘会与该行框的顶部对齐。

如果因当前行剩余水平空间不足而放不下一个浮动框,则该浮动框会下移,直到找到放得下它的位置或者当前位置以下已没有更多浮动出现。

因为浮动不属于正常排版流(flow),在浮动框前面和后面被创建的非定位块框会如同该浮动不存在一样地垂直排版。但是,当前和随后的紧挨着浮动框被创建的行框,会按需要缩短其宽度来为浮动框的外边距框让出空间。

一个行框会紧挨一个浮动的前提是有某个垂直位置能满足以下四个条件:

  • (a)在行框的顶部或以下;
  • (b)在行框的底部或以上;
  • (c)在浮动框顶外边缘以下;
  • (d)在浮动框底外边缘以上。
注:这意味着外部高度为0或负数的浮动框不会使行框的宽度缩短。

如果被缩短后的行框过小,以至于它无法容纳任何内容,则应使该行框下移(并重新计算其可用宽度),直到它能容纳一些内容,或其下方已无其它浮动框。当前行中位于浮动框前面的任何内容要在浮动的另一边重新排版。换句话说,如果已有行级框摆放入当前行,再遇到一个左浮框可放入行框剩余的空间,则该左浮框会摆放在该行,并与行盒顶部对齐,然后之前已放入行盒内的行内框会被移到该左浮框的右边(右边算是左浮框的另一边)重新摆放。反过来对rtl和右浮动也一样。

table、块级的可替换元素,或者在正常排版流中创建了新块格式化上下文的元素Note.png,此类元素的border框必须与同一个块格式化上下文中任何浮动框的外边距框没有重叠。如果需要,具体的实现可把该元素放在之前出现的所有浮动框下方,以清除浮动的效果,但如果有足够的空间来摆放该元素就应该把它摆放在浮动框旁边。他们可能甚至使得上述元素的框比章节10.3.3中定义的更窄。CSS2对用户代理何时可将上述元素紧挨着浮动或上述的元素可以变窄多少并没有定义。

例如。在下面的文档片段,浮动框的包含块已经窄到无法在该浮动旁边放入其后继的内容。于是该浮动框的后继内容被移动到浮动的下面,并按text-align属性指定的对齐方式在行框内进行对齐。

p { width: 10em; border: solid aqua; } span { float: left; width: 5em; height: 5em; border: solid blue; }

..。

<p> <span> </span> Supercalifragilisticexpialidocious </p>

这片段显示出来可能像这样:

supercal.png

几个浮动可以是并排的,这个模型同样适用于在同一行并排的浮动。

接下来的规则会让 class="icon" 的所有IMG框向左浮动(并把左外边距设置为'0'):

img.icon { float: left; margin-left: 0; }

考虑下面的HTML源码和样式:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <HTML> <HEAD> <TITLE>Float example</TITLE> <STYLE type="text/css"> IMG { float: left } BODY, P, IMG { margin: 2em } </STYLE> </HEAD> <BODY> <P><IMG src=img.png alt="This image will illustrate floats"> Some sample text that has no other..。 </BODY> </HTML>

IMG框被浮动到左边。其随后的内容会从该浮动框的同一行开始,被排版到浮动的右边。在浮动框右边的行框由于该浮动的存在而被缩短。但在浮动之后恢复它们的"正常"宽度(也就是它的由P元素创建的包含块的宽度)。该文档可能被格式化成:

floateg.png

如果文档像下面这样,则格式化的结果将完全相同:

<BODY> <P>Some sample text <IMG src=img.png alt="This image will illustrate floats"> that has no other..。 </BODY>

这是因为浮动左边的内容会被浮动侵占了位置,并要在浮动的右边重新排版。

章节8.3.1所说的,浮动框与其并排框的外边距绝不会发生折叠。因此,在前面的例子中,在P框和浮动的IMG框之间的垂直外边距不会折叠

浮动框的内容会像它生成了新的堆叠上下文(stacking contexts)那样被堆叠起来,除了定位元素和创建了新的堆叠上下文并参加了其浮动的父级堆叠上下文的元素。 浮动框能与正常排版流中的其它框出现重叠(例如,当正常排版流中的框紧跟着浮动且其外边距为负值)。当重叠发生时,浮动框要绘制在正常排版的非定位块之上(front),而在正常排版的行内框之下(behine)。

这里有另一个例子,演示了当浮动框与正常排版流中一个元素的边框出现重叠时会是怎样的情形。
float2p.png
一个浮动的图片遮蔽了与其重叠的块盒的边框。

下一个例子演示了使用'clear'属性去阻止内容紧挨着一个浮动。

假设有规则如下:

p { clear: left }

排版效果看起来应该像这样:

floatclear.png
两段文本都设置了 'clear: left', 这使第二段文本被推到了浮动框下边的位置 — 在其上外边距的上方插入了 "间隙" 来达到这样的效果(见 'clear' 属性)。

确定浮动的位置:'float'属性 Positioning the float: the 'float' property

'float'

取值: right | none | inherit
初始: none
適用於: 除了章节9.7描述之外的所有元素
繼承:
百分比: (不适用)
媒介: 图形
計算值: 同指定值

该属性指定一个框是应该向左或向右浮动,还是完全不浮动。它可设置在任何元素,但它只适用于生成了非绝对定位框的所有元素。该属性取值的含义如下:

left

该元素生成一个向左浮动的框。内容紧挨着该框的右边,并从顶部开始排列(受限于'clear'属性)。

right

和'left'相同,除了框向右浮动,内容紧挨着框的左边,并从顶部开始排列。

none

该框不浮动。

用户代理可把根元素当作不浮动来处理。

以下是用来控制浮动效果的一些更精确的规则:

  1. 左浮框的左外边缘不可位于其包含块左边缘之左。对于右浮框也有类似的规则。
  2. 若当前框为左浮框,且在源文档中先前有元素已产生了任何左浮框,那么对于每个这样的先前框,要么当前框的左外边缘位于先前框的右外边缘之右,要么当前框的顶部必须位于先前框的底部之下。对于右浮框也有类似的规则。
  3. 左浮框的右外边缘不可位于其右方的任何右浮框的左外边缘之右。对于右浮框也有类似的规则。
  4. 浮动框的顶外边缘不可以高于其包含块的顶部。当浮动出现在两个折叠的外边距之间,则该浮动的定位就好像在排版流中插入了另一个空的父级匿名块。要按照在外边距折叠的章节中定义的规则对该父级匿名块进行定位。
  5. 浮动框的顶外边缘不可以高于源文档中其先前元素产生的块框浮动框的顶外边缘。
  6. 浮动框的顶外边缘不可以高于源文档中其先前元素产生的框所在的行框的顶边。
  7. 如果一个左浮框的左方有另外一个左浮框,则其右外边缘不可位于其包含块的右边缘之右。(或者比较宽松的要求是:一个左浮动框除非它已经紧挨其包含块的左边缘,否则它不可以超出其包含快的右边缘。)对于向右浮动的元素也有类似的规则。
  8. 一个浮动框要放置得尽可能的高。
  9. 一个左浮动框必须尽量靠左放置,一个右浮动框必须尽量靠右放置。在更高的位置和更靠左或靠右的位置之间,选择前者。

在块格式化上下文中,如果浮动框有垂直外边距的取值为负数,并使该浮动框的位置在其原本的位置(假如这些垂直外边距取值为0)的上方,则CSS2.1对该浮动框的位置没有定义。

这些规则中所说的其它元素仅仅是指与浮动框在同一个块格式化上下文的其它元素。

这个HTML片段的效果是让b向右浮动。

<P>a<SPAN style="float: right">b</SPAN></P>

如果P元素有足够的宽度,则a和b将会并排,它应该看起来像:

float-right.png

控制跟在浮动后而的排版流:'clear'属性

'clear'

取值: left | right | both | inherit
初始: none
適用於: 块级元素
繼承:
百分比: (不适用)
媒介: 图形
計算值: 同指定值

该属性表明元素的框的哪一边不能与先前的浮动框相邻。'clear'属性不考虑在元素自身或者在其它块格式化上下文里面的浮动。

当应用于非浮动的块框时,取值的含义如下:

left

要求框的顶边框边低于在源文档中之前生成的任何左浮动框的底外边距边。

right

要求框的顶边框边低于在源文档中之前生成的任何右浮动框的的底外边距边。

both

要求框的顶边框边低于在源文档中之前生成的任何浮动框的底外边距边。

none

对框相对于浮动框的位置没有额外的约束。

除了'none' 以外的值潜在地引入间隙。间隙会阻止外边距折叠,并充当一个元素上外边距之上的间隔。间隙会推动元素垂直地越过浮动。

对一个设置了'clear'属性的元素,其间隙的计算是先确定该元素上边框边的假定位置。这个位置是当元素的'clear'属性值为'none'时上边框边所在的位置。

如果元素上边框边的假定位置没有越过相关的浮动,那么引入间隙,并按 8.3.1 中的规则来进行外边距的折叠。

间隙的高度设置为以下较大者:

  1. 让待摆放的块框的边框边缘与位于最下方的被清除的浮动框的外边缘不出现相交时所需的最小间隔高度。
  2. 让待摆放的块框的顶边框边缘们于其clear为none时假定的位置时所需的间隔高度。

作为一种选择,间隙的高度可以直接等于以上第一项的高度。

注:这两种实现方式都允许对存在网页内容的兼容性进行不定求值(pending evaluation)。未来的CSS规范将明确要求使用其中的一个或者另一个。
注:注意:间隙可以是负数或0。
例 1.简单起见,假定我们只有3个框,在这个规则中:块B1带有bottom margin M1(B1没有子元素,没有padding也没有border),浮动块F有height H,块B2带有top margin M2(没有padding,没有border,也没有子元素)。B2的'clear'设置为'both'。我们同样假设B2不为空。

不考虑B2的'clear'属性,我们有下面图表的情形。B1和B2的margin重叠。我们说B1的底border边在y=0的位置。然后,F的顶部在y=M1的位置,B2的顶border边在y=max(M1,M2),F的底部在 y = M1 + H。

clearance.png

我们同样假设B2不在F下面,也就是说:

max(M1,M2) < M1 + H

在这种假设下,根据规范的描述,需要引入间隙。

要得到间隙的数值,我们首先需要使用两种计算方式计算出两个间隙,C1和C2,然后取两者中的最大值:C=max(C1,C2)。第一种方式是让B2的顶部和F的底部齐平,也就是在 y = M1 + H.那意思是,因为使用了清除它们之间的margin不再重叠:

bottom of F= top border edge of B2?

M1 + H= M1 + C1 + M2?

C1= M1 + H - M1 - M2

= H - M2

第二种计算方式是保持B2的顶部不变,也就是在 y= max(M1,M2)。 那意思是:

max(M1,M2)= M1 + C2 + M2?

C2= max(M1,M2) - M1 - M2

我们假设max(M1,M2) < M1 + H,其意味着:

C2 = max(M1,M2) - M1 - M2< M1 + H - M1 - M2 = H - M2?

C2< H - M2

且,由于C1 = H - M2,于是:

C2 < C1

因此

C = max(C1,C2) = C1

例2.一个清除为负数情形下的例子,在这里清除是-1em.(假设没有元素有border和padding):

<p style="margin-bottom: 4em"> First paragraph。 <p style="float: left; height: 2em; margin: 0"> Floating paragraph。 <p style="clear: left; margin-top: 3em"> Last paragraph.

说明:没有'clear',首个和末尾段落的margin将重叠,并且最后的段落的顶部border边将和浮动段落的顶部对齐。但是'clear'要求顶border边在浮动下面。也就是降低2em.这个意思是空隙必须引入。相应地,margin不再重叠且空隙的总数设置结果是clearance + margin-top = 2em,也就是clearance = 2em - margin-top = 2em - 3em = -1em.

当 clear 属性设置在浮动元素上时,会导致浮动定位规则的改变。一个额外的约束(#10)被添加:

  • 浮动的顶部外边必须低于所有之前的left-floating框(就'clear:left'来说)的底部外边,或者所有right-floating框(就'clear: right'来说), 或者 both ('clear: both')。
注:注意:这个属性适用于所有 CSS1中元素。 实现可以在所有元素上支持该属性。在CSS2和CSS2.1'clear'属性仅仅应用于块级元素。因此程序设计者应该只把该属性用在块级元素上。如果一个实现支持内联元素的clear,而不是设置一个上面解释的清除,实现应该强制一个打断和有效的插入一个或多个空的行框(或偏移新的行框向下就像章节9.5)来移动顶部的被清除内联行框到各自的浮动框下面。

绝对定位 Absolute positioning

在绝对定位模型中,一个框基于它的包含块而显式地偏移。它完全从正常排版中脱离(对后继的兄弟没有影响)。一个绝对定位框为它的正常排版子元素和绝对地定位(不是fixed)后代生成一个新的包含块。不过,绝对定位元素的内容不会在其它框的周围排列。它们可能会也可能不会挡住另外一个框的内容(或者被挡住),这取决于互相重合的框的堆叠层次

本规范中如果引用到一个绝对定位元素(或它的框)隐含着该元素的'position'属性设置为'absolute'或'fixed'。

固定定位 Fixed positioning

固定定位是绝对定位的一个子类。唯一的区别是,对于固定定位框,它的包含块由视口创建。对于连续媒介,固定框并不随着文档的滚动而移动。从这个意义上 说,它们类似于固定的背景图形。对于页面媒介,固定定位框在每页里重复。需要在每一页底部放置一个签名时,这个方法很有用。如果一个固定定位框的大小大于整个页面的大小,多余的部分会被裁切。

作者可以使用固定定位来创建类似框架的呈现。考虑如下的框架布局:
frame.png

可以通过如下的HTML文档和样式表来达到这一效果:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> <HTML> <HEAD> <TITLE>A frame document with CSS2</TITLE> <STYLE type="text/css"> BODY { height: 8.5in } /* Required for percentage heights below */ #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; } </STYLE> </HEAD> <BODY> <DIV id="header"> ... </DIV> <DIV id="sidebar"> ... </DIV> <DIV id="main"> ... </DIV> <DIV id="footer"> ... </DIV> </BODY> </HTML>

'display'、'position' 与 'float' 的关系 Relationships between 'display', 'position', and 'float'

影响框的生成和布局的三个属性——'display','position'和'float'——间的相互关系如下:

  1. 如果'display'值为'none',那么'position''float'无效,元素不生成框。
  2. 否则,如果'position'值为'absolute'或者'fixed',框绝对地定位'float'计算的值为'none',并且 display根据下面的表格进行设定。框的位置由'top', 'right', 'bottom''left'属性和包含块决定。
  3. 否则,如果'float'的值不是'none',该框是浮动的,且'display'值根据下面的表格进行设定。
  4. 否则,如果元素是根元素,'display'值根据下面的表格进行设定,除了其在CSS2.1里面没有定义是否指定值'list-item'对应计算值'block'或者'list-item'。
  5. 否则,'display' 的计算值为指定的值。
指定值 计算值
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
其他 与指定值相同

正常排版,浮动和绝对定位的对比 Comparison of normal flow, floats, and absolute positioning

为了演示正常排版,相对定位,浮动和绝对定位间的区别,我们提供一系列的例子,它们都基于如下的HTML片段:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> <HTML> <HEAD> <TITLE>Comparison of positioning schemes</TITLE> </HEAD> <BODY> <P>Beginning of body contents。 <SPAN id="outer"> Start of outer contents。 <SPAN id="inner"> Inner contents.</SPAN> End of outer contents.</SPAN> End of body contents。 </P> </BODY> </HTML>

在文档中,我们假定有如下规则:

body { display: block; font-size:12px; line-height: 200%; width: 400px; height: 400px } p { display: block } span { display: inline }

正常排版 Normal flow

考虑如下的outerinner的CSS声明,它们并不改变正常排版框:

#outer { color: red } #inner { color: blue }

P元素包含所有的行内内容:匿名行内文本以及两个SPAN元素。因此所有的内容将在一个行格式化内容中得到排列,包含在一个由P元素生成的包含块中,看起来如下图:

flow-generic.png

相对定位 Relative positioning

要看到相对定位的效果,我们规定:

#outer { position: relative; top: -12px; color: red } #inner { position: relative; top: 12px; color: blue }

文本正常排列直到outer元素。outer的文本在第一行结尾排列到它的正常流向的位置和尺寸。然后包含文字行内框(分三行排列)移动了'-12px'单位(向上)。

inner的内容,作为outer的子元素,正常地应该紧接"of outer contents"排列(在第1.5行)。不过,inner的内容自身相对outer内容偏移'12px'(向下),而回到它原来的位置第二行。 注意跟随在outer之后的内容并不受outer相对定位的影响。

flow-relative.png

还要注意,如果outer的偏移是'-24px',那么outer的文本和主体文本会重合。

让框浮动 Floating a box

现在考虑浮动inner元素的效果,我们通过如下规则将它的文本向右浮动:

#outer { color: red } #inner { float: right; width: 130px; color: blue }

文本正常排列直到inner框,它从流向中脱离并浮动到右外边距(它的'width'是显式指定的)。浮动左边的行框被缩短,文档的其余文本流入里面。

flow-float.png

要显示'clear'属性的效果,我们在例子中加入一个兄弟元素:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> <HTML> <HEAD> <TITLE>Comparison of positioning schemes II</TITLE> </HEAD> <BODY> <P>Beginning of body contents。 <SPAN id=outer> Start of outer contents。 <SPAN id=inner> Inner contents.</SPAN> <SPAN id=sibling> Sibling contents.</SPAN> End of outer contents.</SPAN> End of body contents。 </P> </BODY> </HTML>

和如下规则:

#inner { float: right; width: 130px; color: blue } #sibling { color: red }

这就使inner框和以前一样向右浮动,而文档的其余文本流入空出的地方:

flow-clear.png

但是,如果兄弟元素的'clear'属性设置为'right'(即,生成的兄弟框不接受在右边有浮动框相邻的位置),则兄弟的内容在浮动之下开始排列:

#inner { float: right; width: 130px; color: blue } #sibling { clear: right; color: red }
flow-clear2.png

绝对定位 Absolute positioning

最后,我们考虑绝对定位的效果。考虑如下的outerinner的CSS声明:

#outer { position: absolute; top: 200px; left: 200px; width: 200px; color: red; } #inner { color: blue }

这就使outer框的顶部的定位基于它的包含块。定位框的包含块由最靠近的定位的父辈创建(或者,如果不存在这样的父辈,则采用初始包含块,就像在本例中)。outer框的顶部在包含块顶部 '200px'之下,左边在包含块左边'200px'。outer框的子框的排列相对于outer框正常排列。

flow-absolute.png

下面的例子展示了一个相对定位框中的一个绝对定位的子框。尽管outer父框并没有实际偏移,设置它的'position'属性为'relative' 意味着这个框可以作为定位派生内容的包含块。由于outer框是一个行内框并跨越几行分布,第一个行内框的顶和左边(在图形中用粗点线标出)作为 'top''left'偏移的参考。

#outer { position: relative; color: red } #inner { position: absolute; top: 200px; left: -100px; height: 130px; width: 130px; color: blue; }

结果可能看起来是这样的:

flow-abs-rel.png

如果我们不定位outer框:

#outer { color: red } #inner { position: absolute; top: 200px; left: -100px; height: 130px; width: 130px; color: blue; }

inner框的包含块成为用初始包含块(在我们的例子中)。下面的例子展示了这种情况下。inner框最终的位置。

flow-static.png
相对和绝对定位可以用来实现变更栏,下例是这一实现的演示。考虑如下文档:

<P style="position: relative; margin-right: 10px; left: 10px;"> I used two red hyphens to serve as a change bar. They will "float" to the left of the line containing THIS <SPAN style="position: absolute; top: auto; left: -1em; color: red;">--</SPAN> word.</P>

可能呈现为:

changebar.png
首先,该段落(包含块在图形中也显示出来)正常排列。然后它从包含块的左边偏移'10px'(从而为该偏移保留了'10px'的右外边距)。两个作为变更栏的连字号从正常排版中脱离,并定位在当前行(由于'top: auto')。相对它的包含块(由最终位置的P创建)的左边移动'-1em'。结果是变更栏看上去"浮动"在当前行的左边。

层的呈现 Layered presentation

指定堆叠层次:'z-index'属性 Specifying the stack level: the 'z-index' property

'z-index'

取值: <integer> | inherit
初始: auto
適用於: 定位元素
繼承:
百分比: N/A
媒介: 图形
計算值: {{{7}}}

对于一个定位框,'z-index'属性指定了:

  1. 当前堆叠内容中框的堆叠层次。
  2. 该框是否生成局部堆叠内容。

取值的含义如下:

<length>

该整数是生成的框在当前堆叠内容中的堆叠层次。该框也生成了一个局部堆叠内容,在其中它的堆叠层次是'0'。

auto

生成的框在当前堆叠内容中的堆叠层次和它的父框相同。该框不生成新的局部堆叠内容。

在该章节中,表达式"in front of"意思是更接近用户因为用户面对屏幕。

在CSS 2.1中,每个框在3个维度(dimensions)有个定位。除了水平和垂直的位置,框沿着"z-轴"展现并且被格式化成一个在其他的上面。当框在视觉上重叠了Z-轴定位特别地重要。这个章节谈论框怎样沿着z-轴定位。

渲染的树绘到canvas上的顺序描述是依照堆叠上下文。堆叠上下文能包含更深层的堆叠上下文。一个堆叠上下文从它的父级堆叠上下文的观点来看是原子的;在其它堆叠上下文的框可能不干涉它的任何框。

每个框属于一个堆叠上下文。每个定位的框在给出的堆叠上下文有一个整数的堆叠级别,堆叠级别是它在相同堆叠上下文里面z-轴相对于其它堆叠级别的位置。有较大堆叠级别的框总是会被格式化在较低堆叠级别框的前面。框可以有负的堆叠级别。框在同样的堆叠上下文中有同样的堆叠级别根据文档树顺序由后到前堆放。

根元素形成根堆叠上下文。其它由任意定位的元素生成(包含相对定位元素)的堆叠上下文有一个可计算的'z-index'值不同于'auto'。堆叠上下文不一定与包含块相关。在未来CSS的等级,其它属性可以引入堆叠上下文,例如'opacity'[CSS3COLOR]

在每个堆叠上下文中,下面的层在从后到前的顺序中绘出:

  1. background和元素的borders形成堆叠上下文。
  2. 子堆叠上下文有负的堆叠级别(大多是负的在前面)。
  3. 属于正常排版的,非行级,非定位的后代。
  4. 非定位的浮动。
  5. 正常排版,行级,非定位后代,包含inline tables和inline块。
  6. 堆叠级别为0的子堆叠上下文和堆叠级别为0的定位后代。
  7. 子堆叠上下文有正的堆叠级别(最小的正数优先)

在每个堆叠上下文,定位元素的堆叠级数为0(第6层),非定位浮动(第4层),内联块(5层),还有inline table(5层),被渲染好像那些元素本身生成新的堆叠上下文,除了它们定位的后代和任意将是子堆叠上下文参与当前的堆叠上下文。

该渲染顺序递归地应用到每个堆叠上下文。该堆叠上下文渲染顺序的描述构成附录E详细规范定义的概述。

在下面的例子中,各个框(以它们的"id"属性命名)的堆叠层次是:"text2"=0,"image"=1,"text3"=2,"text1"=3。"text2"的堆叠层次从它的根框继承而来。其它的由'z-index'属性指定。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> <HTML> <HEAD> <TITLE>Z-order positioning</TITLE> <STYLE type="text/css"> .pile { position: absolute; left: 2in; top: 2in; width: 3in; height: 3in; } </STYLE> </HEAD> <BODY> <P> <IMG id="image" class="pile" src="butterfly.gif" alt="A butterfly image" style="z-index: 1"> <DIV id="text1" class="pile" style="z-index: 3"> This text will overlay the butterfly image。 </DIV> <DIV id="text2"> This text will be beneath everything。 </DIV> <DIV id="text3" class="pile" style="z-index: 2"> This text will underlay text1, but overlay the butterfly image </DIV> </BODY> </HTML></span>

本例演示了透明的概念。一个框的缺省行为是允许在它后面的框透过它内容中透明的区域而可见。本例中,每个框透明地覆盖它下面的框。这一行为可以通过使用某个现成的背景属性而被重写。

文本方向:'direction''unicode-bidi'属性

遵照用户端不支持双向文本可以忽略'direction''unicode-bidi'属性在该章节描述。该例外包括用户端简单地从右至左渲染字符。因为一个系统上的字体包含它们但是不支持从右到左文本方向的概念。

在某些脚本中,文字是从右到左书写的。某些文档中,特别是以阿拉伯或希伯来文写成的文档中,以及一些溷合语言的内容中,单一(视觉上显示的)块中文字的排列也有不同的方向。这一现象称为双向排列或简称为“双向”。

Unicode标准([UNICODE],[UAX9]) 定义了一个复杂的算法来确定文字正确的方向。该算法包含了基于字符属性的隐式部分,以及对于嵌入和重写的显式控制。CSS2依赖这一算法来获得正确的双向渲染。'direction''unicode-bidi'属性允许作者规定文档语言的元素和属性如何与该算法相匹配。

用户端支持双向文本必须应用Unicode双向算法到每个行级框的序列且该序列不被强制(bidi class B)中断或者块外边距打断。这个序列在双向算法中形成"paragraph"(段落)单元。该段落嵌入级别通过包含块的'direction'属性的值进行设置而不是通过Unicode算法在步骤P2和P3中给出的启发式heuristic来设置。

由于文字的方向性取决于文档语言的结构和语意,在大多数情况下,这些属性应该只由文档类型描述(DTD)的设计者或特殊文档的作者使用。如果一个缺省样式表指定了这些属性,作者和用户不应该指定重写它们的规则。一个常见的例外可能是,如果一个用户端在用户的要求下将犹太语(通常以希伯来字母写成)音译为拉丁字母时,用户端重写了双向表现。

HTML 4.0规范([HTML40],8.2节)定义了HTML元素的双向排列行为。一致的HTML用户端可能在作者和用户的样式表里忽略 'direction'和'unicode-bidi'属性。在[HTML4]中指定的那些可能产生双向行为的规则出现在示例样式表中。HTML 4.0规范也包含了有关双向排列事项的更多的信息。

'direction'

取值: rtl | inherit
初始: ltr
適用於: 所有元素,但参见描述
繼承:
百分比: N/A
媒介: 图形
計算值: {{{7}}}

该属性指定了块的基本书写方向,以及Unicode双向算法中嵌入和重写的方向(参见'unicode-bidi')。另外,它还规定了表格列布局的方向,水平溢出的方向,以及块设置了'text-align: justify'时,最后一个不完全的行的位置。

该属性取值的含义如下:

ltr

左到右的方向。

rtl

右到左的方向。

要使'direction'属性对行内元素有影响,'unicode-bidi'属性的值必须是'embed'或'override'。

注:注意。'direction'属性指定给表格列元素时,并不被列内的单元格继承,这是因为列不存在于文档树中。因此,对于 [HTML4],11.3.2.1节中描述的"dir"属性的继承规则,CSS不可能很容易地保持。

'unicode-bidi'

取值: embed | bidi-override | inherit
初始:

normal

適用於: 所有元素,但参见描述
繼承: no
百分比: N/A
媒介: 图形
計算值: {{{7}}}

该属性取值的含义如下:

normal

基于双向算法,元素不打开一个额外的嵌入层次。对于行内元素,在元素的外边距中隐含了重排列的工作。

embed

如果元素是行内的,基于双向算法,该值打开一个额外的嵌入层次。该嵌入层次的方向由'direction'属性给出。在元素内,重排列隐式地完成。这相当 于在元素的开头加入一个LRE(U+202A;对于'direction: ltr')或RLE(U+202B;对于'direction: rtl'),在元素的结尾加入一个PDF(U+202C)。

bidi-override

如果元素是行内的,或者是只包含行内元素的块类元素,该值创建一个超越。这意味着在元素内,重排列严格按照'direction'属性的顺序;双向算法的隐式部分被忽略。这相当于在元素的开头加入一个LRO(U+202D;对于'direction: ltr')或RLO(U+202E;对于'direction: rtl'),在元素的结尾加入一个PDF(U+202C)。

每一个块类元素的字符的最终的顺序就如同:双向控制代码如上所述加入,标记被剥离,结果的字符顺序传递给用于普通文字的Unicode双向算法实现,该实现产生和样式文本一样的分行。在这一处理中,非文字实体如图形被认为是中性字符,除非它们的'unicode-bidi'属性不是设置为 'normal'。在这一情况下,它们被认为是为该元素指定的'direction'中的重要字符。

请注意,为了能够在一个单一方向(要么全部左到右,要么全部右到左)中排列行内框,必须创建更多的行内框(包括匿名行内框),而且某些行内框在排列之前,可能必须分割或重排。 由于Unicode算法限制嵌入的层次为15层,将'unicode-bidi'设置为非'normal'的使用,必须小心,除非确定是合适的。特别地,使用'inherit'值时要特别小心。不过,对于那些一般来说显示为块的元素,更应该设置'unicode-bidi: embed',这样在显示改变到行内时,可以将元素保持在一起(见下例)。

下面的例子显示了包含双向文字的一个XML文档。它演示了一个重要的设计原则:DTD设计者应该在语言语言(元素和属性)和任何相关联的样式表中考虑双向 因素。样式表的设计应该是双向规则和其它样式表规则分离。双向规则不应该被其它样式表规则超越,从而文档语言或DTD的双向行为得以保留。

本例中,小写字母表示左到右的字符而大写字母表示右到左的字符:

<HEBREW> <PAR>HEBREW1 HEBREW2 english3 HEBREW4 HEBREW5</PAR> <PAR>HEBREW6 <EMPH>HEBREW7</EMPH> HEBREW8</PAR> </HEBREW> <ENGLISH> <PAR>english9 english10 english11 HEBREW12 HEBREW13</PAR> <PAR>english14 english15 english16</PAR> <PAR>english17 <HE-QUO>HEBREW18 english19 HEBREW20</HE-QUO></PAR> </ENGLISH>

由于这是一个XML,样式表负责设置书写方向。样式表如下:

/* Rules for bidi */ HEBREW, HE-QUO {direction: rtl; unicode-bidi: embed} ENGLISH {direction: ltr; unicode-bidi: embed} /* Rules for presentation */ HEBREW, ENGLISH, PAR {display: block} EMPH {font-weight: bold}

HEBREW元素是一个块,基本方向是右到左,ENGLISH元素是一个块,基本方向是左到右。PAR元素是块,基本方向从父元素继承。因此,前两个 PAR从右顶部开始阅读,最后的三个从左顶布开始阅读。请注意元素名选择HEBREW和ENGLISH只是为了明显表示而已;一般情况下,元素名应该反映结构而不反映语言。

EMPH元素是行内元素,而且它的'unicode-bidi'设置为'normal'(初始值),它对文字的排列没有影响。另一方面,HE-QUO元素创建一个嵌入。 如果行宽足够的长,这些文字的格式化效果可能是:

5WERBEH 4WERBEH english3 2WERBEH 1WERBEH 8WERBEH 7WERBEH 6WERBEH english9 english10 english11 13WERBEH 12WERBEH english14 english15 english16 english17 20WERBEH english19 18WERBEH

注意,HE-QUO嵌入使HEBREW18出现在english19之右。

如果需要分行,可能效果是:

2WERBEH 1WERBEH -EH 4WERBEH english3 5WERB -EH 7WERBEH 6WERBEH 8WERB english9 english10 en- glish11 12WERBEH 13WERBEH english14 english15 english16 english17 18WERBEH 20WERBEH english19

由于HEBREW18必须在english19前阅读,它在english19所在行的上面。仅仅是在前一格式化例子中分割长行不会有用。还要注意 english19的第一个音节可能可以放在上一行中。但是,为了避免在一行的中间出现一个连字符,在右到左的内容中,左到右单词的连字通常被禁止。反之亦然。

下一章:视觉格式化模型细节