CSS2中的可视化格式模型(2)_Visual fomatting model in CSS2(2)

9.7 ‘display’,’position’和’float’间的相互关系 Relationships between ‘display’, ‘position’, and ‘float’

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

  1. 如果’display’值为’none’,那么’position’和’float’无效,元素不生成盒子.
  2. 否则,如果’postion’值为’absolute’或者’fixed’,盒子绝对地定位’float’计算的值为’none’,并且 display根据下面的表格进行设定.盒子的位置由’top’, ‘right’, ‘bottom’和’left’属性和包含块决定.
  3. 否则,如果’float’的值不是’none’,该盒子是浮动的,且’display’值根据下面的表格进行设定.
  4. 否则,如果元素是根元素,’display’值根据下面的表格进行设定,除了其在CSS2.1里面没有定义是否’list-item’的指定值成为’block’或者’list-item’计算值.
  5. 否则,应用指定的其它’display’属性.


















    指定值 Specified value计算值 Computed value
    inline-tabletable
    inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-blockblock
    otherssame as specified

9.8 常规流向,浮动和绝对定位的对比 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; }

9.8.1 常规流向 Normal flow

考虑如下的outer和inner的CSS声明,它们并不改变常规流盒子:

#outer { color: red; }

#inner { color: blue; }

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

Image illustrating the normal flow of text between parent and sibling boxes. [D]

9.8.2 相对定位 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相对定位的影响.

Image illustrating the effects of relative positioning on a box [D]

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

9.8.3 浮动一个盒 Floating a box

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

#outer { color: red; }

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

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

Image illustrating the effects of floating a box. [D]

要显示’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盒和以前一样向右浮动,而文档的其余文本流入空出的地方:

Image illustrating the effects of floating a box without setting the clear property to control the flow of text around the box. [D]

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

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

#sibling { clear: right; color: red; }

Image illustrating the effects of floating an element with setting the clear property to control the flow of text around the element. [D]

9.8.4 绝对定位 Absolute positioning

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

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

#inner { color: blue; }

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

Image illustrating the effects of absolutely positioning a box. [D]

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

#outer {
position: relative;
color: red;
}

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

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

Image illustrating the effects of absolutely positioning a box with respect to a containing block. [D]

如果我们不定位outer盒:

#outer { color: red }

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

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

Image illustrating the effects of absolutely positioning a box with respect to a containing block established by a normally positioned parent. [D]

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

<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>

可能呈现为:

Image illustrating the use of floats to create a changebar effect. [D]

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

9.9 分层的呈现 Layered presentation

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

‘z-index’
值: auto | <integer> | inherit
初始值: auto
适用于: 定位元素
可否继承: 否
百分比: N/A
媒介: 图形

对于一个定位盒,’z-index’属性指定了:

当前堆叠内容中盒的堆叠层次。
该盒子是否生成局部堆叠内容。
取值的含义如下:

<integer>
该整数是生成的盒在当前堆叠内容中的堆叠层次。该盒也生成了一个局部堆叠内容,在其中它的堆叠层次是’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”
src=”butterfly.gif” alt=”A butterfly image”
style=”z-index: 1”>

<DIV id=”text1”
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”
style=”z-index: 2”>
This text will underlay text1, but overlay the butterfly image
</DIV>
</BODY>
</HTML>

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

9.10 文本方向:’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’属性。在[HTML40]中指定的那些可能产生双向行为的规则出现在示例样式表中。HTML 4.0规范也包含了有关双向排列事项的更多的信息。

‘direction’
值: ltr | rtl | inherit
初始值: ltr
适用于: 所有元素,但参见描述
可否继承: 可
百分比: N/A
媒介: 图形

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

该属性取值的含义如下:

ltr
左到右的方向。
rtl
右到左的方向。
要使’direction’属性对行内元素有影响,’unicode-bidi’属性的值必须是’embed’或’override’。

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

‘unicode-bidi’
值: normal | embed | bidi-override | inherit
初始值: normal
适用于: 所有元素,但参见描述
可否继承: no
百分比: N/A
媒介: 图形

该属性取值的含义如下:

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的第一个音节可能可以放在上一行中。但是,为了避免在一行的中间出现一个连字符,在右到左的内容中,左到右单词的连字通常被禁止。反之 亦然。