层叠样式表第2级 CSS2规范开发手册 - WEB前端开发 专注前端开发,关注用户体验

9 可视化格式模型

    目录

9.1 可视化格式模型简介

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

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

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

    可视化格式模型并不指定格式化的所有方面(例如,它并不指定字符间距算法)。与CSS一致的用户端在处理本规范未包含的格式化情形时,表现可能有所不同。

9.1.1 视点

    连续媒介的用户端通常提供给用户一个视点(屏幕上的一个窗口或浏览区域),通过它用户来浏览文档。当视点尺寸改变时,用户端可能改变文档的布局(参见初始包含块)。如果视点比文档的初始包含块小,用户端可能提供滚动机制。对于一个渲染区域而言,最多只能有一个视点,不过用户端可以对多个渲染区域加以渲染(即对同一文档提供不同的视点)。

9.1.2 包含块

    CSS2中,很多框的位置和尺寸的计算都基于一个被称为包含块的长方形盒子的四边。通常地,生成的框表现为其派生框的包含块;我们说一个框“建立”了它的派生框的包含块。短语“一个框的包含块”意味着“该框所存在的那个包含块”,而不是它所生成的块。

    基于框的包含块,每一个框都有一个定位,不过它不被包含块所限制;它可能溢出

    文档树的根生成一个框,作为后继布局的初始包含块

    初始包含块的宽度可以由根元素的'width'属性指定。如果该属性取值为'auto',用户端提供初始宽度(如,用户端使用视点的当前宽度)。

    初始包含块的高度可以由根元素的'height'属性指定。如果该属性取值为'auto',包含块的高度将调整以适应文档内容。

    初始包含块不可以被定位或浮动(即,用户端忽略根元素的'position''float'属性)。

    包含块尺寸如何计算的细节的描述在下一篇

9.2 控制包含框的生成

    下面的几节描述了CSS2中可能生成的包含框的类型。一个框的类型部分地影响它在可视化格式模型中的表现。以下讨论的'display'属性决定了框的类型。

9.2.1 块类元素和块控制框

    块类元素是源文档中那些在视觉上被格式化为块(如:段落)的那些元素。某些'display'属性的取值产生块类元素:'block','list-item','compact'和'run-in'(某些时候;参见压缩的控制框插入的控制框),以及'table'。

    块类元素生成一个原始块控制框,它只包含块控制框。原始块控制框生成派生框和生成内容的包含块,并且是在任何定位方案中都要牵涉到的框。元素块控制框参与块格式化的内容

    某些块类元素在原始框之外生成额外的框:'list-item'元素和那些带有标记的元素。这些额外的框根据原始框来定位。

匿名块控制框

    有这样一个文档:

<DIV>
  Some text
  <P>More text
</DIV>
(并假定DIV和P都设置了'display: block'),DIV看来包含行内和块内容。为了使格式化简单一些,我们假定有一个匿名块控制框围绕在"Some text"周围。

    diagram showing the three
boxes for the example above   [D]

图形显示上例中三个控制框,其中一个是匿名的。

    换句话说:如果一个块控制框(如上例中为DIV生成的框)在其中包含另外一个块框(如上例中的P),我们强迫它在其内包含块框,而将任何的行内框都包含在一个匿名块框之内。

例子:

    这一模型对下面的例子适用。如果如下的规则:

/* Note: HTML UAs may not respect these rules */
BODY { display: inline }
P    { display: block }

    应用在如下的HTML文档中:

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

    BODY元素包含一个匿名文本块(C1),后跟另一个匿名文本块(C2)。最后的控制框是BODY的一个匿名块控制框,包含C1周围的一个匿名块控制框,P块控制框,以及另外一个C2周围的匿名块控制框。

    匿名框的属性从包含它的非匿名框那里继承而来(本例中,是DIV的控制框)。不能继承的属性取它们的初始值。例如,匿名框的字体从DIV继承,但是边距为0。

9.2.2 行内类元素和行内控制框

    行内元素源文档中那些不形成新的内容块的元素;内容在行内分布(如,段落内着重的文本,行内图形等等)。某些'display'属性的取值形成洋行内元素:'inline','inline-table','compact'和'run-in'(某些时候;参见压缩的控制框插入的控制框)。行内元素生成行内控制框

    行内控制框可以参与几个格式化的内容:

匿名行内控制框

    在如下的文档中:

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

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

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

    如果根据上下文可以确定匿名框是哪种类型,匿名行内控制框和匿名块控制框在本规范中都被称为匿名控制框(匿名框)。

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

9.2.3 压缩的控制框

    一个压缩的控制框表现行为如下:

    压缩框在边距中的定位方法如下:它在块的第一个行框的外边(左边或右边),不过它影响那个行框高度的计算。压缩框的'vertical-align'属性确定压缩框相对于该行框的垂直位置。压缩框的水平位置总是在块框的边距内。

    如果一个元素不可以被格式化在一行内,它就不能放置在下一个块的边距中。例如,一个HTML中的'compact'元素包含一个BR元素总是被格式化为一个块框(适用BR元素的缺省样式,即插入一个新行)。要在边距中放置多行文本,使用'float'属性可能更加合适。

    下例演示了一个压缩的控制框:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
  <HEAD>
    <TITLE>A compact box example</TITLE>
    <STYLE type="text/css">
      DT { display: compact }
      DD { margin-left: 4em }
    </STYLE>
  </HEAD>
  <BODY>
    <DL>
      <DT>Short
        <DD><P>Description goes here.
      <DT>too long for the margin
        <DD><P>Description goes here.
    </DL>
  </BODY>
</HTML>

    本例可能格式化为:

short    Description goes here

too long for the margin
         Description goes here

    'text-align'属性可以用来在边距内对齐压缩的元素:对齐边距的左边('left'),对齐右边('right')或居中('center')。值'justify'不适用,并被理解为或者是'left',或者是'right',取决于压缩元素在其中格式化的块类元素的'direction'。(如果方向是'ltr',则靠左;如果方向是'right',则靠右。)

    请参见生成的内容一节,以了解压缩的框和生成的内容之间互相作用的内容。

9.2.4 插入的控制框

    一个插入的控制框表现如下:

    一个'run-in'框在插入标题时很有用,如下例:

    

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
  <HEAD>
    <TITLE>A run-in box example</TITLE>
    <STYLE type="text/css">
      H3 { display: run-in }
    </STYLE>
  </HEAD>
  <BODY>
    <H3>A run-in heading.</H3>
    <P>And a paragraph of text that
       follows it.
  </BODY>
</HTML>

    本例可能被格式化为:

  A run-in heading. And a
  paragraph of text that 
  follows it.

    插入元素的属性继承自源树中它的父元素,而不是来自视觉上它成为其一部分的那个块框。

    请参见生成的内容一节,以了解插入框如何与生成的内容交互作用的信息。

9.2.5 'display'属性

'display'
值:  inline | block | list-item | run-in | compact | marker |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
适用于:  所有元素
可否继承:  
百分比:  N/A
媒介:  所有

    该属性取值的含义如下:

block
该值使一个元素生成一个原始块框。
inline
该值使一个元素生成一个或多个行内框。
list-item
该值使一个元素(如HTML中的LI)生成一个原始块框和一个列表项行内框。要了解列表和列表格式化的信息,请参见列表一节。
marker
该值声明了在一个框之前或之后的生成的内容为一个标记。该值只能和与块类元素相连的:before和:after伪元素结合使用。在其它情况下,该值被理解为'inline'。更多的信息请参见标记一节。
none
该值使一个元素在格式化结构产生框(即,该元素对布局没有影响)。派生的元素也不产生任何框;该行为不能由设置派生元素的'display'属性而被超越。

请注意'none'的显示特性并不生成一个不可见的框;它根本不生成框。CSS包含了机制使一个元素能够在格式化结构中生成框而影响格式化,但本身不可见。请参见可视性一节以获得详细叙述。

插入压缩
根据上下文,这些值要么生成块框,要么生成行内框。对于插入和压缩框适用的属性基于它们最终的状态(行内或块类)。例如,'white-space'属性仅在框成为块框时才适用。
tableinline-tabletable-row-grouptable-columntable-column-grouptable-header-grouptable-footer-grouptable-rowtable-celltable-caption
这些值使一个元素表现为类似一个表格元素(还要考虑在表格一章中讨论到的限制)。

    注意,尽管'display'初始值是'inline',用户端的缺省样式表可以超越它。参见附录中的HTML 4.0示例样式表

例子:

    

    这里是一些'display'属性的例子:

P   { display: block }
EM  { display: inline }
LI  { display: list-item } 
IMG { display: none }      /* Don't display images */

    一致的HTML用户端可以忽略'display'属性。

9.3 定位方案

    CSS2中,一个控制框的布局可以根据三种定位方案

  1. 常规流向。CSS2中,常规流向包含框的块格式化行内框的行内格式化,块框或行内框的相对定位,以及压缩插入框的定位。
  2. 浮动。在浮动模型中,一个框首先根据常规流向布局,再将它从流中取出并尽可能地向左或向右偏移。内容可以排列在一个浮动的边上。
  3. 绝对定位。在绝对定位模型中,一个框整个地从常规流向中脱离(它对后续的同胞没有影响),并根据一个包含块来分配其定位。
注意。CSS2的定位方案帮助作者使它们的文档更容易阅读,而不需要使用定位技巧(如不可见的图形)来达到布局效果。

9.3.1 选择定位方案:'position'属性

    'position''float'属性指定选择哪个CSS2定位方案来计算框的定位。

'position'
值:  static | relative | absolute | fixed | inherit
初始值:  static
适用于:  所有元素,除了生成的内容
可否继承:  
百分比:  N/A
媒介:  图形

    该属性取值的含义如下:

static
该框是一个常规的控制框,布局根据常规流向'left''top'属性不适用。
relative
框的位置根据常规流向计算(被称为常规流向中的位置)。然后框相对于它的常规位置而偏移。如果B框是相对定位的,接下去的框的定位计算并不考虑B的偏移。
absolute
框的位置(可能还有它的尺寸)是由'left''right''top''bottom'属性决定。这些属性指定了基于框的包含块的偏移。绝对定位的框从常规流向中脱离。这意味着它们对其后的同胞的定位没有影响。同样的,尽管绝对定位框有边距,它们不会和其它边距发生重合(塌缩)。
fixed
框的定位的计算基于'absolute'模型,不过还要额外地根据一些参考而得到固定。在连续媒介的情况下,框的位置基于视点固定(媒介滚动时并不移动)。在页面媒介的情况下,框的位置基于页面而固定,即使该页面通过一个视点而呈现(例如在打印预览的情况下)。作者可能希望以媒介相关的方式来指定'fixed'。例如,一个作者可能希望一个框总是在一个屏幕视点的顶端,但并不是在每一个打印页的顶端。这两个规则可以使用@media规则加以分割,如:

例子:

    

   
@media screen { 
  H1#first { position: fixed } 
}
@media print { 
  H1#first { position: static }
}

9.3.2 控制框偏移'top''right''bottom''left'

    如果一个元素的'position'属性值的取值不是'static'的话,该元素被称为定位的。定位的元素生成定位框,其定位基于四个属性:

'top'
值:  <length> | <percentage> | auto | inherit
初始值:  auto
适用于:  定位的元素
可否继承:  
百分比:  基于包含块的高度
媒介:  图形

    该属性指定一个框的内容的顶边相对该框的包含块的顶边向下偏移的量。

'right'
值:  <length> | <percentage> | auto | inherit
初始值:  auto
适用于:  定位的内容
可否继承:  
百分比:  基于包含块的宽度
媒介:  图形

    该属性指定一个框的内容的右边相对该框的包含块的右边向左偏移的量。

'bottom'
值:  <length> | <percentage> | auto | inherit
初始值:  auto
适用于:  定位的内容
可否继承:  
百分比:  基于包含块的高度
媒介:  图形

    该属性指定一个框的内容的底边相对该框的包含块的底边向上偏移的量。

'left'
值:  <length> | <percentage> | auto | inherit
初始值:  auto
适用于:  定位的内容
可否继承:  
百分比:  基于包含块的宽度
媒介:  图形

    该属性指定一个框的内容的左边相对该框的包含块的左边向右偏移的量。

    这四个属性的取值的含义如下:

<length>
偏移是距离参照边的固定值。
<percentage>
偏移是包含块宽度(对于'left''right')或高度(对于'top''bottom')的百分比。对于'top'和'bottom',如果包含块的高度没有显式指定(即它取决于内容的高度),百分比值将解释为'auto'。
auto
该值的效果取决于与之相关的属性中的哪一个也设置了'auto'。详细的内容请参见绝对定位,非替换元素的宽度高度一节。

    对于绝对定位框,偏移是基于框的包含块。对于相对定位框,偏移是基于该框本身的外边界(即根据常规流向给予框一个位置,偏移相对于这些属性而计算)。

9.4 常规流向

    常规流向中的框属于一个格式化内容,可能是块或者是行内,但不能同时都是。框参与块格式化内容。行内框参与行内格式化内容。

9.4.1 块格式化的内容

    在块格式化内容中,框一个接一个地垂直放置,起点是一个包含块的顶部。两个同胞框之间的垂直距离取决于'margin'属性。在块格式化内容中相邻的框的垂直边距会重合

    在块格式化内容中,每一个框左外边与包含块的左边相接触(对于从右到左的格式化,右外边接触右边),即使存在浮动也是如此(尽管一个框的内容区域会由于浮动而压缩)。

    有关在页面媒介中分页的信息,请参见允许的分页一节。

9.4.2 行内格式化的内容

    在行内格式化内容中,框一个接一个地水平排列,起点是包含块的顶部。水平边距,边框和边白在框之间得到保留。框在垂直方向的对齐可以有不同的方式:它们的顶部或底部对齐,或对齐在其中的文字的基线。包含形成一条线的那些框的长方形区域成为一个线框

    线框的宽度取决于一个包含块。它的高度取决于行高的计算一节中给出的规则。对于线框包含的框来说,它的高度总是足够的。不过,它可能比它包含的最高的框要高(例如,框对齐而引起基线对齐)。如果B框的高度小于包含它的线框的高度,B的垂直对齐由'vertical-align'属性决定。

    如果几个行内框在水平方向无法放入一个线框内,它们可以分配在两个或多个垂直层叠的线框中。因此,一个段落就是线框的垂直方向上的堆叠。线框堆叠时没有垂直方向的分割并且永不重合。

    一般而言,线框的左边接触到其包含块的左边,右边接触到包含块的右边。不过,浮动框可能出现在包含块的边和线框的边之间。因此,尽管同一个行内格式化内容中的线框通常宽度相同(等于包含块的宽度),它们可能由于浮动而减少了可用的水平空间而改变宽度。同一行内格式化内容的线框通常高度不一样(如,一行包含了一个高的图形,而其它行只包含文本)。

    如果一行中线框宽度之和小于包含它们的线框的宽度,它们在线框内的水平分布取决于'text-align'属性。如果属性取值为'justify',用户端也可能延伸行内框。

    由于一个行内框可能不会超过一个线框的宽度,长的行内框将分成几个框,而这些框分布在几个线框内。如果一个行内框发生分割,边距、边框和边白在分割发生的地方没有视觉上的效果。如果在双向嵌入内发生分割,边距、边框和边白的格式化可能没有被完全定义。

    行内框还可能由于双向文本处理在同一个线框内被分割为好几个框。

    下面是一个行内框构造的例子。接下来的一段(HTML块类元素P产生)包含由元素EM和STRONG间隔的匿名文本:

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

    P元素产生一个块框,包含了五个行内框,其中的三个是匿名的:

    为了格式化这一段,用户端将这五个框排入线框。本例中,为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的宽度,这些框可能分配如下:

    Image illustrating the effect of line breaking on the display of margins, borders, and padding.   [D]

9.4.3 相对定位

    一旦一个框按照常规流向得到定位,它还可以相对该位置而偏移。这就是相对定位。这样来偏移一个框(B1)将不会对后继的框(B2)有任何影响:给予B2的位置就好象B1没有偏移,并且在B1偏移后,B2也不会重新定位。这意味着相对定位可能产生框的重合。

    相对定位的控制框保持它们通常的大小,包括分行以及原来为它们保留的位置。一个相对定位的框创建一个新的包含块来包含常规流向中的子元素 和定位的派生元素。

    要产生一个相对定位的框,可以设置元素的'position'属性为'relative'。偏移量由'top''bottom''left''right'属性指定。

    相对定位框的动态移动在脚本环境中可以产生动画效果(也参见'visibility'属性)。相对定位也可以用来作为上标和下标的通用形式,只是行高不会因考虑定位而自动调整。更多的信息参见行高的计算

    相对定位的例子参见常规流向,浮动和绝对定位的对比

9.5 浮动

    浮动框就是一个框在当前行向左或向右偏移。浮动框最有趣的特性是内容可以在它的边的周围排列(或设置'clear'属性而被禁止)。内容排列在左浮动框的右边,而排列在右浮动框的左边。下面是关于浮动定位和内容排列的简介;决定浮动行为的确切的规则'float'属性的描述中给出。

    一个浮动框必须有一个显式的宽度(通过'width'属性指定,或对于替换元素是它的内在宽度)。任何浮动框都成为一个块框,它不断向左或向右偏移直到它的外边接触到包含块的边或另外一个浮动的外边。浮动框的顶部和当前线框的顶部对齐(如果没有线框,则对齐前面一个块框的底部)。如果当前行没有足够的水平空间来包含该浮动,则它逐行向下移动直到某一行有足够的空间容纳它。

    由于一个浮动框并不在流向中,在该浮动框之前或之后创建的非定位框垂直排列,就好象该浮动框并不存在一样。不过紧接着该浮动创建的线框将缩短而给浮动框以空间。在浮动框之前当前行的任何内容将重新排列在浮动框另一边第一个可用的行上。

    几个浮动可以相邻,本模型也适用于一行中的相邻浮动。

例子:

    下面的规则将所有class="icon"的IMG框浮动到左边(并将左边距设置为):

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

    考虑如下HTML源文件和样式表:

  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//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.gif alt="This image will illustrate floats">
       Some sample text that has no other...
  </BODY>
</HTML>

    IMG框浮动到左边。跟随的内容在浮动的右边进行格式化,开始于浮动的同一行。由于浮动的出现,浮动右边的线框缩短了,但是在浮动之后恢复它们“正常”的宽度(由P元素生成的包含块的宽度)。本文档可能被格式化为:

    Image illustrating how floating boxes interact with
margins.   [D]

    如果文档是如下的内容,格式化效果一样:

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

    这是因为浮动左边的内容将被浮动占据,并重新定位到它的右边。

    浮动框的边距从不和其相邻的框的边距重合。因此,在上例中,P框和浮动的IMG框间的垂直边距并不重合

    一个浮动可以覆盖常规流向中其它的框(如与浮动相邻的常规流向框的边距为负数)。如果一个行内框覆盖一个浮动框,该行内框的内容、背景和边框在该浮动前面渲染。如果一个块框覆盖一个浮动框,块框的背景和边框在浮动后面渲染,并只有在浮动为透明时才可见。块框的内容在浮动前面渲染。

例子:

    下面是另外一个演示,说明了一个浮动覆盖了常规流向中的元素边框时的情况。

    Image showing a floating image
that overlaps the borders of two paragraphs: the borders are
interrupted by the image.   [D]

一个浮动的图形使被它覆盖的块框的边框不可见。

    下面的例子展示了如何使用'clear'属性来禁止内容在一个浮动周围排列。

例子:

    假定有这样一个规则:

P { clear: left }

    则格式化可能看上去是这样的:

    Image showing a floating
image and the effect of 'clear: left' on the two paragraphs.   [D]

两个段落都设置了'clear: left',这使得第二段被“往下推”到浮动之下的位置——它的顶边距也相应扩大来与之配合(参见'clear'属性)。

9.5.1 浮动的定位:'float'属性

'float'
值:  left | right | none | inherit
初始值:  none
适用于:  除了定位的元素和生成的内容之外的所有元素
可否继承:  
百分比:  N/A
媒介:  图形

    该属性指定一个框是否应该向左,向右浮动或不浮动。它适用于产生控制框但不是绝对定位的所有元素。该属性取值的含义如下:

left
该元素产生一个框,并向左浮动。内容在该框的右边排列,起点是框的顶部(除非还设置了'clear'属性)。 'display'被忽略,除非它的值是'none'。
right
和'left'相同,不过内容排列在框的左边,起点是框的顶部。
none
该框不浮动。

    下面是一些更精确的规则来控制浮动的表现:

  1. 向左浮动的框的左外边不可以出现在它的包含块左边界之左。对于向右浮动的元素也有类似的规则。
  2. 如果当前的框向左浮动,并且在源文档中先前有元素产生了任何向左浮动的框,那么对于每一个这样的先前的框,要么当前框的左外边出现先前框的右外边之右,要么它的顶部必须在先前的框的底部之下。对于向右浮动的框也有类似的规则。
  3. 向左浮动的框的右外边不可以出现在它右边的任何向右浮动的框的左外边之右。对于向右浮动的元素也有类似的规则。
  4. 一个浮动框的顶边不可以高于它的包含块的顶。
  5. 浮动框的顶边不可以高于源文档中先前的元素产生的浮动框的顶。
  6. 一个元素的顶边不可以高于源文档中先前的元素产生的包含一个框的任何线框的顶。
  7. 向左浮动的框如果在它左边有另外一个向左浮动的框,它的右外边不可以出现在它的包含块的右边之右。(或者比较宽松的要求是:一个左浮动不可以超出右边,除非它已经尽可能地靠左排列。)对于向右浮动的元素也有类似的规则。
  8. 一个浮动框要放置得尽可能的高。
  9. 一个左浮动框必须尽量靠左放置,一个右浮动框必须尽量靠右放置。在更高的位置和更靠左或靠右的位置间,选择前者。

9.5.2 控制紧接浮动的排列:'clear'属性

'clear'
值:  none | left | right | both | inherit
初始值:  none
适用于:  块类元素
可否继承:  
百分比:  N/A
媒介:  图形

    该属性表明一个元素的框的哪一边可以和一个先前的浮动框相邻。(它可以包含浮动的后代;'clear'对它们没有影响。)

    该属性仅适用于块类元素(包括浮动)。对于压缩插入框,该属性适用于压缩框或插入框属于的最后的块框。

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

left
生成的框的顶边距将增加,直到它的顶边出现在源文档中先前的元素产生的任何向左浮动的框的底外边之下。
right
生成的框的顶边距将增加,直到它的顶边出现在源文档中先前的元素产生的任何向右浮动的框的底外边之下。
both
生成的框将移到源文档中先前的元素产生的浮动框之下。
none
对考虑到浮动后的框的位置没有约束。

    如果属性设置在浮动元素上,结果是对浮动定位的规则做了改动,加入了额外的约束(#10):

9.6 绝对定位

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

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

9.6.1 固定定位

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

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

    Image illustrating a frame-like layout with position='fixed'.   [D]

    可以通过如下的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>

9.7 'display','position'和'float'间的相互关系

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

  1. 如果'display'设置为'none',用户端必须忽略'position''float'。在这种情况下,元素不产生框。
  2. 否则,'position'设置为'absolute'或'fixed','display'设置为'block'且'float'设置为'none'。框的位置将由'top''right''bottom''left'属性和该框的包含块确定。
  3. 否则,如果'float'的值不是'none','display'设置为'block'并且该框浮动。
  4. 否则,应用指定的其它'display'属性。

     注意。 CSS2并没有规定这些属性的值被脚本改变后布局的表现。例如,如果一个元素设置了'width: auto'并且重新定位,会发生什么?内容是重新排列,还是保留原来的格式?答案已经超出了本规范的范围,而且在初期的CSS2实现中,表现可能互不相同。

9.8 常规流向,浮动和绝对定位的对比

    为了演示常规流向,相对定位,浮动和绝对定位间的区别,我们提供一系列的例子,它们都基于如下的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; line-height: 200%; 
       width: 400px; height: 400px }
P    { display: block }
SPAN { display: inline }

    各个例子中,由outerinner元素产生的框的最终的位置都不同。每一个演示中,图形左边的数字表明双重空白间隔行(为了看起来更清楚)在常规流向中的位置。(注意:图形的水平和垂直比例是不同的。

9.8.1 常规流向

    考虑如下的outerinner的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 相对定位

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

#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's content.   [D]

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

9.8.3 控制框的浮动

    现在考虑浮动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 绝对定位

    最后,我们考虑绝对定位的效果。考虑如下的outerinner的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'的右边距)。两个作为更改条的连字号从常规流向中脱离,并定位在它的包含块(有最终位置的P创建)的当前行(由于'top: auto'),相对左边移动'-1em'。结果是更改条看上去“浮动”在当前行的左边。

9.9 分层的呈现

    下面的段落中,“在前面”是指当用户面对屏幕时,更靠近用户。

    CSS2中,每一个框都有一个三维的定位。除了它们的水平和垂直定位,框排列在一个“Z轴”上,格式化时一个框在另一个框的顶上。Z轴定位在框有视觉上的重合时特别重要。本节讨论框如何在Z轴上定位。

    每个框属于一个堆叠内容。某个给顶的堆叠内容中的每个框都有一个整数的堆叠层次,它规定了该框在同一堆叠内容中相对于其它框在Z轴上的位置。堆叠层次大的框总是在堆叠层次小的框的前面格式化。框可以有负的堆叠层次。如果堆叠内容中的框具有相同的堆叠层次,它们根据文档树中出现的次序而由底到顶堆叠。

    元素创建了一个根堆叠内容,不过其它元素可能生成局部堆叠内容。堆叠内容是可继承的。一个局部堆叠内容是原子化的;在其它堆叠内容中的框不可以出现在任何它的框之间。

    创建局部堆叠内容的一个元素生成一个框,包含两个堆叠层次:洋是它创建的堆叠内容(总是'0'),另一个是它所属的堆叠内容(由'z-index'属性指定)。

    一个元素的框和它的父框具有相同的堆叠层次,除非另外由'z-index'属性指定了一个不同的堆叠层次。

9.9.1 指定堆叠层次'z-index'属性

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

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

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

    取值的含义如下:

<integer>
该整数是生成的框在当前堆叠内容中的堆叠层次。该框也生成了一个局部堆叠内容,在其中它的堆叠层次是'0'。
auto
生成的框在当前堆叠内容中的堆叠层次和它的父框相同。该框不生成新的局部堆叠内容。

    

    在下面的例子中,各个框(以它们的"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>

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

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

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

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

    如果一个文档中包含右到左的字符,并且用户端显示这些字符(以正确的字符图标显示,而不是任意地用问号、十六进制符号或一个黑框等来代替),该用户端必须采用双向排列算法。这一看上去是单向的要求反映了这样一个事实,即尽管并不是每一个希伯来文或阿拉伯文的文档包含混合方向的文本,这样的文档比那些以从左到右语言写成的文档(可能包含右到左的文字)更可能包含左到右的文本(如,数字,其它语言的文字)。

    由于文字的方向性取决于文档语言的结构和语意,在大多数情况下,这些属性应该只由文档类型描述(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'属性指定给表格列元素时,并不被列内的单元格继承,这是因为列不存在于文档树中。因此,对于[HTML40],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的第一个音节可能可以放在上一行中。但是,为了避免在一行的中间出现一个连字符,在右到左的内容中,左到右单词的连字通常被禁止。反之亦然。