9 可视化格式模型

内容

9.1 可视化格式模型介绍

本章和下一章描述了可视化格式模型:用户代理如何处理文档树以用于可视媒体

在可视化格式模型中,文档树中的每个元素根据框模型生成零个或多个框。这些框的布局受以下因素影响:

本章和下一章中定义的属性适用于连续媒体分页媒体 然而,当应用于分页媒体时,外边距属性的含义有所不同(详见页面模型)。

可视化格式模型并未规定所有格式化的细节(例如,它没有指定字母间距算法)。符合标准的用户代理可能在本规范未涵盖的格式化问题上表现不同。

9.1.1 视口

针对连续媒体的用户代理通常为用户提供一个视口(屏幕上的一个窗口或其他查看区域),用户通过视口来查看文档。当视口大小调整时,用户代理可能会改变文档的布局(参见初始包含块)。

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

9.1.2 包含块

在 CSS 2.2 中,许多框的位置和尺寸是相对于一个称为包含块的矩形框的边缘来计算的。通常,生成的框作为后代框的包含块;我们称一个框“建立”了其后代的包含块。短语“一个框的包含块”指的是“框所在的包含块”,而不是它生成的那个。

每个框的位置是相对于其包含块给出的,但它不受该包含块的限制;它可能会溢出

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

9.2 控制框生成

以下部分描述了在 CSS 2.2 中可能生成的框类型。框的类型部分地影响其在可视化格式模型中的行为。下面描述的'display'属性指定了框的类型。

某些'display'属性的值会使源文档的一个元素生成一个包含后代框和生成内容的主要框,并且该框也参与任何定位方案。一些元素除了主要框外还可能生成其他框:'list-item'元素。这些附加的框是相对于主要框放置的。

9.2.1 块级元素和块框

块级元素 – 源文档中那些在视觉上被格式化为块的元素(例如段落)– 是生成块级主要框的元素。使一个元素成为块级的'display'属性值包括:'block'、'list-item'和'table'。块级框是参与块格式化上下文的框。

在 CSS 2.2 中,块级框也是块容器框,除非它是表格框或替换元素的主要框。一个块容器框要么只包含块级框,要么建立一个内联格式化上下文,因此只包含内联级框。主要框是块容器框的元素是一个块容器元素。使非替换元素生成块容器的'display'属性值包括'block'、'list-item'和'inline-block'。并非所有块容器框都是块级框:非替换内联块和非替换表格单元格是块容器但不是块级框。既是块级框又是块容器的块级框称为块框

“块级框”、“块容器框”和“块框”这三个术语有时可以在上下文明确的情况下简写为“块”。

9.2.1.1 匿名块框

在这样的文档中:


<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),那么我们强制它内部包含块级框。

当一个内联框包含一个流内块级框时,内联框(及其在同一行框内的内联祖先)会在块级框(以及任何连续的块级兄弟或仅由可折叠的空白字符和/或流外元素分隔的兄弟)周围断开,将内联框分成两个框(即使任一侧为空),分别位于块级框的两侧。断开前后的行框被封装在匿名块框中,而块级框成为这些匿名框的兄弟。当这样的内联框受到相对定位的影响时,任何产生的平移也会影响内联框中包含的块级框。

示例:

如果使用以下规则,此模型将适用于以下示例:


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

与这个 HTML 文档一起使用:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HEAD>
<TITLE>被块打断的匿名文本</TITLE>
</HEAD>
<BODY>
<P>
这是在 SPAN 之前的匿名文本。
<SPAN>这是 SPAN 的内容。</SPAN>
这是在 SPAN 之后的匿名文本。
</P>
</BODY>

P 元素包含一块(C1)匿名文本,后面跟着一个块级元素,再后面跟着另一块(C2)匿名文本。生成的框将是表示 BODY 的块框,包含一个围绕 C1 的匿名块框、SPAN 块框和另一个围绕 C2 的匿名块框。

匿名框的属性是从包围它的非匿名框继承的(例如,在“小节标题‘匿名块框’”下方的示例中,继承自 DIV 的属性)。非继承属性具有其初始值。例如,匿名框的字体从 DIV 继承,但外边距将为 0。

设置在导致生成匿名块框的元素上的属性仍然适用于该元素的框和内容。例如,如果在上述示例中的 P 元素上设置了边框,则边框将围绕 C1(在行的末端开放)和 C2(在行的起始开放)绘制。

一些用户代理以其他方式实现了包含块的内联框的边框,例如,通过将这些嵌套块包装在“匿名行框”内,从而围绕这些框绘制内联边框。由于 CSS1 和 CSS2 并未定义此行为,因此仅支持 CSS1 和 CSS2 的用户代理可能会实现此替代模型,并且仍声称符合 CSS 2.2 的这一部分。这不适用于在本规范发布后开发的用户代理。

在解析将引用匿名块框的百分比值时,将忽略匿名块框:改为使用最近的非匿名祖先框。例如,如果 DIV 内的匿名块框的子元素需要知道其包含块的高度以解析百分比高度,那么它将使用由 DIV 形成的包含块的高度,而不是匿名块框的高度。

9.2.2 内联级元素和内联框

内联级元素是源文档中不会形成新的内容块的那些元素;内容分布在行中(例如段落中的强调文本、内联图像等)。以下'display'属性值使元素成为内联级:'inline'、'inline-table'和'inline-block'。 内联级元素生成内联级框,这些框是参与内联格式化上下文的框。

内联框是既为内联级又参与其包含的内联格式化上下文的框。具有'display'值为'inline'的非替换元素生成一个内联框。不是内联框的内联级框(例如替换的内联级元素、内联块元素和内联表格元素)被称为原子内联级框,因为它们在内联格式化上下文中作为一个单一的、不透明的框参与。

9.2.2.1 匿名内联框

任何直接包含在块容器元素中的文本(不在内联元素内)必须被视为匿名内联元素。

在具有如下 HTML 标记的文档中:


<p>Some <em>emphasized</em> text</p>

<p>生成一个块框,其中包含几个内联框。"emphasized" 的框是由内联元素(<em>)生成的内联框,但其他框("Some" 和 "text")是由块级元素(<p>)生成的内联框。后者被称为匿名内联框,因为它们没有关联的内联级元素。

这些匿名内联框继承自其块父框的可继承属性。非继承属性具有其初始值。在示例中,匿名内联框的颜色继承自 P,但背景是透明的。

根据'white-space'属性后续会被折叠掉的空白内容不会生成任何匿名内联框。

如果从上下文中可以清楚地知道是哪种类型的匿名框,则在本规范中,匿名内联框和匿名块框都简单地称为匿名框。

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

9.2.3 行内块框

[此部分存在的目的是为了使章节编号与之前的草案保持一致。'Display: run-in' 现在在 CSS 第 3 级中定义(请参见 CSS 基本框模型)。]

9.2.4 The 'display' 属性

名称: display
值: inline | 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'属性来覆盖。

请注意,'none' 的 display 并不会创建一个不可见的框;它根本不创建任何框。CSS 包含使元素在格式化结构中生成框的机制,这些框会影响格式化但本身不可见。详情请参阅可见性部分。

tableinline-tabletable-row-grouptable-columntable-column-grouptable-header-grouptable-footer-grouptable-rowtable-cell,以及 table-caption
这些值使元素表现得像表格元素(受限于表格章节中描述的限制)。

计算值与指定值相同,但定位和浮动元素(请参阅"display"、"position" 和 "float" 之间的关系)以及根元素除外。 对于根元素,计算值的更改方式详见"display"、"position" 和 "float" 之间的关系部分。

请注意,虽然初始值'display'是'inline',但用户代理的默认样式表中的规则可能会覆盖此值。请参阅附录中的 HTML 4示例样式表

示例:

以下是'display'属性的一些示例:


p   { display: block }
em  { display: inline }
li  { display: list-item } 
img { display: none }      /* 不显示图像 */

9.3 定位方案

在 CSS 2.2 中,一个框可以根据三种定位方案进行布局:

  1. 正常流。在 CSS 2.2 中,正常流包括块级框的块格式化、内联级框的内联格式化,以及块级和内联级框的相对定位
  2. 浮动。在浮动模型中,框首先根据正常流进行布局,然后从流中移出并尽可能向左或向右移动。内容可以沿着浮动的一侧流动。
  3. 绝对定位。在绝对定位模型中,框完全从正常流中移除(它对后面的兄弟元素没有影响),并相对于包含块分配位置。

如果一个元素是浮动的、绝对定位的或是根元素,则称其为脱离流元素。如果一个元素没有脱离流,则称其为在流中元素。元素A是由A及所有最近的脱离流祖先为A的在流中元素组成的集合。

注意: CSS 2.2 的定位方案通过允许作者避免用于布局效果的标记技巧(例如,隐藏图像),帮助他们使文档更加易于访问。

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

'position''float' 属性决定了使用哪种 CSS 2.2 定位算法来计算框的位置。

名称: position
值: static | 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 和 table-caption 元素的效果是未定义的。
absolute
框的位置(可能还有大小)由 'top''right''bottom''left' 属性指定。这些属性指定相对于框的包含块的偏移。绝对定位的框被从正常流中移除,这意味着它们对后续兄弟元素的布局没有影响。此外,尽管绝对定位的框有外边距,但它们不会与其他外边距折叠
fixed
框的位置是按照 'absolute' 模型计算的,但除此之外,框相对于某个参考点是固定的。与 'absolute' 模型一样,框的外边距不会与任何其他外边距折叠。在 handheld、projection、screen、tty 和 tv 媒体类型的情况下,框是相对于视口固定的,并且在滚动时不会移动。在 print 媒体类型的情况下,框会在每一页上渲染,并且相对于页面框固定,即使页面是通过视口看到的(例如,在打印预览的情况下)。对于其他媒体类型,呈现是未定义的。作者可能希望以依赖媒体的方式指定 'fixed'。例如,作者可能希望一个框保持在屏幕上的视口顶部,但不在每个打印页面的顶部。可以通过使用@media 规则来分隔这两个规范,如下所示:

示例:

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

用户代理不得对固定框的内容进行分页。注意,用户代理可以通过其他方式打印不可见的内容。详见第 13 章的“页面框外的内容”

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

9.3.2 框的偏移'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>
偏移是从参考边缘的固定距离。允许使用负值。
<percentage>
偏移是包含块的宽度(对于'left''right')或高度(对于'top''bottom')的百分比。允许使用负值。
auto
对于非替换元素,此值的效果取决于相关属性中哪些值也为'auto'。有关详细信息,请参见绝对定位、非替换元素的宽度高度部分。对于替换元素,此值的效果仅取决于替换内容的固有尺寸。有关详细信息,请参见绝对定位、替换元素的宽度高度部分。

9.4 正常流

正常流中的框属于一个格式化上下文,在 CSS 2.2 中,格式化上下文可以是表格、块或内联。在未来的 CSS 级别中,将引入其他类型的格式化上下文。块级框参与块格式化上下文。内联级框参与内联格式化上下文。表格格式化上下文在表格章节中描述。

9.4.1 块格式化上下文

浮动元素、绝对定位元素、非块框的块容器(如内联块、表格单元格和表格标题),以及'overflow'属性值不是'visible'的块框(除非该值已传播到视口)为其内容建立新的块格式化上下文。

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

在块格式化上下文中,每个框的左外边缘触碰包含块的左边缘(对于从右到左的格式化,右边缘触碰)。即使存在浮动元素也是如此(尽管框的行框可能因浮动元素而缩小),除非该框建立了新的块格式化上下文(在这种情况下,由于浮动元素,框本身可能变窄)。

关于分页媒体中的分页符信息,请参阅允许的分页符部分。

9.4.2 内联格式化上下文

当一个块容器框中不包含块级框时,会建立内联格式化上下文。在内联格式化上下文中,框从包含块的顶部开始,水平一个接一个地布局。这些框之间会保留水平外边距、边框和内边距。框可以以不同方式垂直对齐:它们的底部或顶部可以对齐,或者它们内部文本的基线可以对齐。包含这些框并形成一行的矩形区域称为行框

行框的宽度由包含块和浮动元素的存在决定。行框的高度由行高计算部分中的规则决定。

行框总是足够高以容纳其包含的所有框。然而,它可能比其包含的最高的框还要高(例如,如果框对齐的方式是基线对齐)。当框 B 的高度小于包含它的行框的高度时,B 在行框内的垂直对齐方式由'vertical-align'属性决定。当多个内联级框无法水平地容纳在一个行框内时,它们会分布在两个或多个垂直堆叠的行框中。因此,段落是行框的垂直堆叠。行框是无垂直间距地堆叠的(除非另有规定),并且它们永不重叠。

通常,行框的左边缘触碰其包含块的左边缘,右边缘触碰其包含块的右边缘。然而,浮动框可能位于包含块边缘和行框边缘之间。因此,尽管同一内联格式化上下文中的行框通常具有相同的宽度(即包含块的宽度),但如果由于浮动元素导致可用水平空间减少,它们的宽度可能会有所不同。同一内联格式化上下文中的行框通常在高度上有所不同(例如,一行可能包含一个高的图像,而其他行仅包含文本)。

当一行中的内联级框的总宽度小于包含它们的行框的宽度时,它们在行框内的水平分布由'text-align'属性决定。如果该属性的值为 'justify',用户代理可能会拉伸内联框中的空格和单词(但不包括内联表格和内联块框)。

当一个内联框超出行框的宽度时,它会被拆分成多个框,并将这些框分布在多个行框中。如果内联框无法拆分(例如,如果内联框包含单个字符,或者语言特定的断词规则不允许在内联框内断开,或者内联框受 nowrap 或 pre 的白空间值影响),则内联框会溢出行框。

当一个内联框被拆分时,拆分处(或有多个拆分时的任意拆分处)不会对边距、边框和内边距产生视觉效果。

由于双向文本处理,内联框也可能在同一行框内被拆分成多个框。

行框是在内联格式化上下文中根据需要创建的,用于容纳内联级内容。对于那些不包含文本、不包含保留的空白、不包含具有非零边距、内边距或边框的内联元素以及不包含其他在流中内容(如图像、内联块或内联表格),并且不以保留换行符结束的行框,应被视为零高度行框来确定其中任何元素的位置,并且在其他目的上应视为不存在。

以下是内联框构造的一个示例。以下段落(由 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.01//EN">
<HTML>
  <HEAD>
    <TITLE>多行内联流示例</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 的宽度,框可能如下分布:

展示行拆分对边距、边框和内边距显示效果的图像   [D]

9.4.3 相对定位

当一个框已经按照正常流或浮动布局后,它可以相对于该位置进行偏移。这称为相对定位。以这种方式偏移一个框(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'。如果包含块的 '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 浮动

浮动框是一个在当前行上向左或向右移动的框。浮动(或“浮动的”或“浮动”框)的最有趣特征是内容可能沿其侧边流动(或被'clear'属性禁止流动)。内容沿左浮动框的右侧流动,沿右浮动框的左侧流动。以下是浮动定位和内容流动的介绍;控制浮动行为的确切规则'float'属性的描述中给出。

浮动框向左或向右移动,直到其外边缘接触到包含块边缘或另一个浮动框的外边缘。如果有行框,浮动框的外上边缘与当前行框的顶部对齐。

如果没有足够的水平空间容纳浮动框,它会向下移动,直到适合为止或不再有浮动框存在。

由于浮动框不在流中,在浮动框之前和之后创建的非定位块框会垂直流动,仿佛浮动框不存在。然而,在浮动框旁边创建的当前和后续行框会根据需要缩短以为浮动框的边距框腾出空间。

当存在以下四个条件时,行框位于浮动框旁边:(a)在行框的顶部或以下,(b)在行框的底部或以上,(c)在浮动框的上边距边缘以下,以及(d)在浮动框的下边距边缘以上。

注意:这意味着外部高度为零或负高度的浮动框不会缩短行框。

如果缩短的行框太小而无法容纳任何内容,则行框会向下移动(并重新计算其宽度),直到某些内容适合或不再有浮动框存在。浮动框之前的当前行中的任何内容都会在同一行的浮动框另一侧重新排版。换句话说,如果在遇到适合剩余行框空间的左浮动框之前将内联级框放置在行上,则左浮动框将被放置在该行上,与行框的顶部对齐,然后该行上的内联级框会相应地移动到浮动框的右侧(右侧是左浮动框的另一侧),对于从右到左的文本和右浮动框则相反。

表格的边框框、块级替换元素或正常流中建立新块格式化上下文的元素(例如 'overflow' 值不是 'visible' 的元素)不得与同一块格式化上下文中任何浮动框的边距框重叠。如果有必要,实施应该通过将该元素放置在任何前面的浮动框下方来清除该元素,但如果有足够的空间,也可以将其放置在这些浮动框旁边。它们甚至可以使该元素的边框框比第 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>

这个片段可能如下所示:

显示一个无法在浮动框旁边容纳的不可拆分内容片段被重新排版到浮动框之后的图像。

多个浮动框可能相邻,这种模型也适用于同一行中的相邻浮动框。

示例:

以下规则将所有带有 class="icon" 的 IMG 框浮动到左侧(并将左边距设为 '0'):


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

请考虑以下 HTML 源代码和样式表:

  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>浮动示例</TITLE>
    <STYLE type="text/css">
      IMG { float: left }
      BODY, P, IMG { margin: 2em }
    </STYLE>
  </HEAD>
  <BODY>
    <P><IMG src=img.png alt="这个图像将说明浮动">
       一些没有其他...的示例文本
  </BODY>
</HTML>

IMG 框被浮动到左侧。后续内容在浮动框右侧进行格式化,从与浮动框同一行开始。由于浮动框的存在,浮动框右侧的行框被缩短,但在浮动框之后恢复其“正常”宽度(即由 P 元素建立的包含块的宽度)。该文档可能被格式化为:

展示浮动框如何与边距交互的图像。   [D]

如果文档是这样的,格式化将完全相同:


<BODY>
  <P>一些示例文本 
  <IMG src=img.png alt="这个图像将说明浮动">
           没有其他...
</BODY>

因为浮动框左侧的内容被浮动框挤开,并在其右侧重新排版。

第 8.3.1 节所述,浮动框的边距永远不会与相邻框的边距折叠。因此,在前面的示例中,P 框和浮动的 IMG 框之间的垂直边距不会折叠

浮动框的内容堆叠,就像浮动框生成了新的堆叠上下文一样,除了任何定位元素和实际创建新堆叠上下文的元素参与浮动框父级的堆叠上下文。浮动框可以与正常流中的其他框重叠(例如,当正常流框旁边的浮动框具有负边距时)。当这种情况发生时,浮动框位于非定位的流内块前面,但在流内内联框的后面。

示例:

这里有另一个例子,展示了当浮动框与正常流中的元素边框重叠时会发生什么。

展示浮动图像如何重叠两个段落的边框:边框被图像遮挡。   [D]

浮动图像遮挡了其重叠的块框的边框。

以下示例说明了使用'clear'属性来防止内容在浮动框旁边流动。

示例:

假设有如下规则:


p { clear: left }

格式化可能如下所示:

显示浮动图像和 'clear: left' 对两个段落的影响的图像。   [D]

两个段落都设置了 'clear: left',这使得第二个段落被“推到”浮动框下方——在其上边距之上添加了“清除”以实现这一点(参见'clear'属性)。

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

名称: float
值: left | right | none | inherit
初始值: none
适用于: 所有元素,但请参见9.7
是否继承:
百分比: 不适用
媒体: 可视媒体
计算值: 如指定的值

该属性指定一个框是否应向左浮动、向右浮动或不浮动。它可以应用于任何元素,但仅适用于生成非绝对定位框的元素。该属性的值具有以下含义:

left
元素生成一个框,向左浮动。内容沿框的右侧流动,从顶部开始(受'clear'属性影响)。
right
类似于 'left',但框向右浮动,内容沿框的左侧流动,从顶部开始。
none
框不浮动。

用户代理可以将根元素的浮动视为 'none'。

以下是控制浮动行为的精确规则:

  1. 左浮动框的左外边缘不得位于其包含块的左边缘的左侧。对于右浮动元素,规则类似。
  2. 如果当前框是左浮动的,并且在源文档中较早生成的元素有任何左浮动框,那么对于每个这样的较早框,要么当前框的左外边缘必须位于较早框的右外边缘的右侧,要么其顶部必须低于较早框的底部。对于右浮动框,规则类似。
  3. 左浮动框的右外边缘不得位于其旁边的任何右浮动框的左外边缘的右侧。对于右浮动元素,规则类似。
  4. 浮动框的外顶部不得高于其包含块的顶部。当浮动框出现在两个折叠的边距之间时,浮动框的位置应当如同它具有一个其他空的匿名块父元素参与流动一样。该父元素的位置由边距折叠部分的规则定义。
  5. 浮动框的外顶部不得高于源文档中较早生成的任何浮动框的外顶部。
  6. 元素的浮动框的外顶部不得高于包含源文档中较早生成的框的任何行框的顶部。
  7. 一个左浮动框如果左侧有另一个左浮动框,则其右外边缘不得超出其包含块的右边缘。(大致来说:左浮动框不得超出右边缘,除非它已经尽可能向左对齐。)对于右浮动元素,规则类似。
  8. 浮动框必须放置在尽可能高的位置。
  9. 左浮动框必须尽可能向左放置,右浮动框尽可能向右放置。较高的位置比更靠左/右的位置更优先。

但在 CSS 2.2 中,如果在块格式化上下文中存在流内负垂直边距,使得浮动框的位置高于所有此类负边距被设置为零时的位置,则浮动框的位置未定义。

这些规则中对其他元素的引用仅指与浮动框在同一块格式化上下文中的其他元素。

示例:

以下 HTML 片段会使 b 向右浮动。

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

如果 P 元素的宽度足够,a 和 b 将并排显示。它可能如下所示:

一个框的左侧显示 a,右侧显示 b 的图像

9.5.2 控制浮动旁边的流动: 'clear'属性

名称: clear
值: none | left | right | both | inherit
初始值: none
适用于: 块级元素
是否继承:
百分比: 不适用
媒体: 可视媒体
计算值: 如指定的值

该属性指示元素框的哪一侧不得与之前的浮动框相邻。'clear' 属性不考虑元素内部或其他块格式化上下文中的浮动。

当应用于非浮动的块级框时,值具有以下含义:

left
要求框的顶部边框边缘位于源文档中较早生成的任何左浮动框的底部外边缘下方。
right
要求框的顶部边框边缘位于源文档中较早生成的任何右浮动框的底部外边缘下方。
both
要求框的顶部边框边缘位于源文档中较早生成的任何左浮动和右浮动框的底部外边缘下方。
none
框的位置不受浮动的约束。

除了 'none' 之外的值可能引入清除间距。清除间距抑制边距折叠,并作为元素的上边距之上的间距。它用于将元素垂直推过浮动。

计算设置了 'clear' 属性的元素的清除间距,首先需要确定元素顶部边框边缘的假设位置。这个位置是如果元素的 'clear' 属性设置为 'none',元素实际的顶部边框边缘会处于的位置。

如果元素顶部边框边缘的假设位置没有超过相关的浮动框,则引入清除间距,并按照 8.3.1 节的规则折叠边距。

然后,清除间距的值设置为以下两者中的较大值:

  1. 将块的边框边缘放置在要清除的最低浮动框的底部外边缘处所需的清除间距。
  2. 将块的顶部边框边缘放置在其假设位置所需的清除间距。

或者,清除间距可以设置为正好足以将块的边框边缘放置在要清除的最低浮动框的底部外边缘处的值。

注意:允许以上两种行为,取决于它们与现有 Web 内容的兼容性评估。未来的 CSS 规范将要求其中之一。

注意:清除间距可以是负值或零。

示例:

示例 1. 假设(为简单起见),我们有三个框,按顺序为:块 B1,底部边距为 M1(B1 没有子元素、没有填充或边框),浮动块 F, 高度为 H,块 B2,顶部边距为 M2(没有填充或边框、没有子元素)。B2 的 'clear' 设置为 'both'。我们还假设 B2 不是空的。

在不考虑 B2 的 'clear' 属性的情况下,我们有如下图所示的情况。B1 和 B2 的边距折叠。假设 B1 的底部边框边缘位于 y = 0 处,则 F 的顶部位于 y = M1 处,B2 的顶部边框边缘位于 y = max(M1,M2) 处,F 的底部位于 y = M1 + H 处。

浮动框 F 延伸到 M2 上方的边距。

我们还假设 B2 不在 F 下方,即我们处于规范中描述的需要添加清除间距的情况。这意味着:

max(M1,M2) < M1 + H

我们需要计算两次清除间距 C1 和 C2,并保留较大的值:C = max(C1,C2)。第一种方法是将 B2 的顶部与 F 的底部对齐,即位于 y = M1 + H。这意味着,由于在它们之间的清除间距导致边距不再折叠:

F 的底部 = 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。(假设所有元素都没有边框或填充):

<p style="margin-bottom: 4em">
  第一段。

<p style="float: left; height: 2em; margin: 0">
  浮动段落。

<p style="clear: left; margin-top: 3em">
  最后一段。

解释:如果没有 'clear',第一段和最后一段的边距会折叠,并且最后一段的顶部边框边缘会与浮动段落的顶部对齐。但 'clear' 要求顶部边框边缘在浮动框下方,即低 2em。这意味着必须引入清除间距。因此,边距不再折叠,并且清除间距的值设置为清除间距 + 上边距 = 2em,即清除间距 = 2em - 上边距 = 2em - 3em = -1em。

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

注意。在 CSS1 中该属性适用于所有元素。因此,实现可能支持此属性在所有元素上应用。在 CSS2 和 CSS 2.2 中,'clear' 属性仅适用于块级元素。因此,作者应该仅在块级元素上使用此属性。如果实现确实支持在内联元素上使用清除,而不是如上所述设置清除间距,实现应强制换行,并有效地插入一个或多个空行框(或如9.5 节中所述将新行框向下移动),将清除的内联元素的行框顶部移到相应浮动框的下方。

9.6 绝对定位

在绝对定位模型中,一个框相对于其包含块明确地偏移。它完全从正常流中移除(对后续的兄弟元素没有影响)。一个绝对定位的框为正常流的子元素和绝对(但不是固定)定位的后代建立了一个新的包含块。然而,绝对定位元素的内容不会围绕任何其他框流动。根据重叠框的堆叠层级,它们可能遮挡其他框的内容(或被其他框遮挡)。

本规范中对绝对定位元素(或其框)的引用意味着该元素的'position'属性的值为 'absolute' 或 'fixed'。

9.6.1 固定定位

固定定位是绝对定位的一个子类别。唯一的区别是,对于固定定位的框,包含块由视口建立。对于连续媒体,当文档滚动时,固定框不会移动。在这一点上,它们类似于固定背景图像。对于分页媒体,具有固定位置的框在每一页上都会重复。这对于在每页底部放置签名等内容很有用。大于页面区域的固定位置框将被裁剪。初始包含块中不可见的固定位置框的部分将不会打印。

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

展示 position='fixed' 的类似框架布局的图像   [D]

这可能通过以下 HTML 文档和样式规则实现:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>A frame document with CSS</TITLE>
    <STYLE type="text/css" media="screen">
      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’,则框为绝对定位,‘float’ 的计算值为 ‘none’,并且 ‘display’ 根据下表设置。框的位置将由 ‘top’‘right’‘bottom’‘left’ 属性及框的包含块决定。
  3. 否则,如果 ‘float’ 的值不是 ‘none’,则框浮动,并且 ‘display’ 根据下表设置。
  4. 否则,如果元素是根元素,‘display’ 根据下表设置,除了在 CSS 2.2 中,指定的 ‘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
其他 与指定值相同

9.8 普通流、浮动和绝对定位的比较

为了说明普通流、相对定位、浮动和绝对定位之间的差异,我们提供了一系列基于以下 HTML 的示例:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//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 }

outerinner元素生成的框的最终位置在每个示例中有所不同。在每个图示中,图示左侧的数字表示双倍行距(为清晰起见)的正常流位置。

注意:本节中的图示是说明性的,比例不准确。它们旨在突出 CSS 2.2 中各种定位方案之间的差异,并不打算作为所给示例的参考渲染。

9.8.1 正常流

考虑以下为outerinner指定的CSS声明,这些声明不会改变框的正常流


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

P元素包含所有内联内容:匿名内联文本和两个SPAN元素。因此,所有内容都将在由P元素建立的包含块内以内联格式化上下文布局,产生类似以下的效果:

展示父级和兄弟框之间的文本正常流动的图像   [D]

9.8.2 相对定位

要查看相对定位的效果,我们指定:


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

文本正常流动直到outer元素。然后,outer文本在行1的末尾按正常流动位置和尺寸布局。接着,包含文本的内联框(分布在三行)整体向上移动‘-12px’。

作为outer的子元素,inner的内容通常会紧跟在“of outer contents”之后(在行1.5)。然而,inner的内容相对于outer的内容被‘12px’(向下)偏移,回到它们在行2的原始位置。

注意,outer之后的内容不会受到outer相对定位的影响。

展示相对定位对框内容影响的图像   [D]

还要注意,如果outer的偏移为‘-24px’,outer的文本和主体文本将会重叠。

9.8.3 浮动框

现在考虑使用以下规则将inner元素的文本向右浮动的效果:


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

文本正常流动直到inner框,它被从流中拉出并浮动到右边的边距(其‘width’已明确指定)。浮动左侧的行框被缩短,文档的其余文本流入其中。

展示浮动框效果的图像   [D]

为了展示‘clear’属性的效果,我们在示例中添加一个sibling元素:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
  <HEAD>
    <TITLE>定位方案比较 II</TITLE>
  </HEAD>
  <BODY>
    <P>正文内容开始。
      <SPAN id=outer> 外部内容开始。
      <SPAN id=inner> 内部内容。</SPAN>
      <SPAN id=sibling> 兄弟内容。</SPAN>
      外部内容结束。</SPAN>
      正文内容结束。
    </P>
  </BODY>
</HTML>

以下规则:


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

导致inner框像以前一样向右浮动,文档的其余文本流入空出的空间:

展示浮动框而未设置clear属性控制文本流动的图像   [D]

但是,如果将sibling元素的‘clear’属性设置为‘right’(即生成的sibling框不接受位于其右侧的浮动框旁边的位置),则sibling内容开始在浮动框下方流动:


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

展示设置clear属性后浮动元素周围文本流动效果的图像   [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的子框相对于其父框正常流动。

展示绝对定位框效果的图像   [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;
}

结果类似于以下内容:

展示相对于包含块进行绝对定位的框的效果   [D]

如果我们不对outer框进行定位:


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

在这种情况下,inner的包含块将成为初始包含块。下图显示了inner框在这种情况下将出现在的位置。

展示相对于由正常定位的父元素建立的包含块进行绝对定位的框的效果   [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>

可能产生类似以下效果:

展示使用浮动创建修改线效果的图像   [D]

首先,段落(包含块边界在图中显示)按正常方式流动。然后它从包含块的左边缘偏移‘10px’(因此,为了预期的偏移,已预留了‘10px’的右边距)。作为修改线的两个红色破折号从流动中移出并定位在当前行上(由于'top: auto'),距离其包含块的左边缘'-1em'(由P元素在其最终位置建立)。结果是修改线似乎“浮动”在当前行的左侧。

9.9 层叠呈现

9.9.1 指定堆叠层级z-index属性

Name: z-index
Value: auto | <integer> | inherit
Initial: auto
Applies to: 定位元素
Inherited: no
Percentages: N/A
Media: 视觉
Computed value: 按指定计算

对于定位框,z-index属性指定:

  1. 框在当前堆叠上下文中的堆叠层级。
  2. 框是否建立一个堆叠上下文。

值的含义如下:

<integer>
此整数是生成的框在当前堆叠上下文中的堆叠层级。该框也建立了一个新的堆叠上下文。
auto
生成的框在当前堆叠上下文中的堆叠层级为0。如果该框的'position'值为fixed或如果它是根元素,它也建立了一个新的堆叠上下文。

在本节中,“在前面”的表达意味着靠近用户,即用户面对屏幕时更靠近用户。

在CSS 2.2中,每个框在三维空间中都有一个位置。除了它们的水平和垂直位置,框还沿着“z轴”排列并依次叠加。当框在视觉上重叠时,z轴位置尤其重要。本节讨论框如何在z轴上定位。

渲染树绘制到画布上的顺序以堆叠上下文的形式描述。堆叠上下文可以包含更多的堆叠上下文。对于其父堆叠上下文而言,堆叠上下文是原子的;其他堆叠上下文中的框不能介于它的任何框之间。

每个框属于一个堆叠上下文。给定堆叠上下文中的每个定位框都有一个整数堆叠层级,这是它在相对于同一堆叠上下文中其他堆叠层级的z轴位置。堆叠层级较大的框始终在堆叠层级较小的框前面显示。框可以具有负堆叠层级。具有相同堆叠层级的框在同一堆叠上下文中按照文档树顺序从后到前进行堆叠。

根元素构成根堆叠上下文。任何具有'auto'以外z-index计算值的定位元素(包括相对定位的元素)都会生成其他堆叠上下文。堆叠上下文不一定与包含块相关联。在CSS的未来版本中,其他属性可能会引入堆叠上下文,例如'透明度' [CSS3COLOR]

在每个堆叠上下文中,以下各层按从后到前的顺序绘制:

  1. 形成堆叠上下文的元素的背景和边框。
  2. 具有负堆叠层级的子堆叠上下文(先绘制负值最大者)。
  3. 流内、非内联级、非定位后代。
  4. 非定位浮动框。
  5. 流内、内联级、非定位后代,包括内联表格和内联块。
  6. 具有堆叠层级为0的子堆叠上下文和具有堆叠层级为0的定位后代。
  7. 具有正堆叠层级的子堆叠上下文(先绘制正值最小者)。

在每个堆叠上下文中,堆叠层级为0的定位元素(在层 6中)、非定位浮动框(层 4)、内联块(层 5)和内联表格(层 5)会像这些元素本身生成了新的堆叠上下文一样绘制,但它们的定位后代和任何将生成的子堆叠上下文会参与当前堆叠上下文。

这种绘制顺序递归地应用于每个堆叠上下文。本描述的堆叠上下文绘制顺序概述了附录 E中详细规范的规范性定义。

在以下示例中,框(以其“id”属性命名)的堆叠层级为:“text2”=0,“image”=1,“text3”=2,“text1”=3。“text2”的堆叠层级从根框继承。其他堆叠层级通过'z-index'属性指定。


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//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.png" 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 文本方向: directionunicode-bidi 属性

符合规范的用户代理(UAs)如果不支持双向文本,可以忽略本节中描述的 directionunicode-bidi 属性。这一例外包括那些仅仅因为系统上的字体包含右到左字符而呈现右到左字符的用户代理,但不支持右到左文本方向的概念。

某些脚本中的字符是从右向左书写的。在某些文档中,尤其是使用阿拉伯语或希伯来语脚本编写的文档,以及一些混合语言的情况下,单个(视觉显示的)块中的文本可能会出现混合方向性。这种现象被称为双向性,简称为“bidi”。

Unicode标准([UNICODE][UAX9])定义了一个复杂的算法,用于确定文本的正确方向性。该算法包括基于字符属性的隐式部分以及用于嵌入和覆盖的显式控制。CSS 2.2依赖此算法实现正确的双向渲染。directionunicode-bidi 属性允许作者指定文档语言的元素和属性如何映射到此算法。

支持双向文本的用户代理必须将Unicode双向算法应用于每个不被强制中断(bidi类 B)或块边界中断的内联级框序列。该序列在双向算法中形成“段落”单元。段落嵌入级别根据包含块的direction属性值设置,而不是通过Unicode算法步骤P2和P3中给出的启发式方法。

由于文本的方向性取决于文档语言的结构和语义,因此这些属性在大多数情况下应仅由文档类型描述(DTD)的设计者或特殊文档的作者使用。如果默认样式表指定了这些属性,作者和用户不应指定规则来覆盖它们。

HTML 4规范([HTML4],第8.2节)定义了HTML元素的双向性行为。在[HTML4]中指定的双向行为可以通过示例样式表中的样式表规则实现。HTML 4规范还包含有关双向性问题的更多信息。

Name: direction
Value: ltr | rtl | inherit
Initial: ltr
Applies to: 所有元素,但请参阅正文
Inherited: yes
Percentages: N/A
Media: 视觉
Computed value: 按指定计算

此属性指定块的基本书写方向以及Unicode双向算法的嵌入和覆盖方向(参见unicode-bidi)。此外,它还指定了诸如表格列布局的方向、水平溢出的方向以及在“text-align: justify”情况下块中不完整最后一行的位置等内容。

此属性的值具有以下含义:

ltr
从左到右的方向。
rtl
从右到左的方向。

要使direction属性影响内联元素的重新排序,unicode-bidi属性的值必须为'embed'或'override'。

注意。direction属性指定给表格列元素时,不会被列中的单元格继承,因为列不是文档树中单元格的祖先。因此,CSS无法轻松捕获[HTML4]第11.3.2.1节中描述的“dir”属性继承规则。

Name: unicode-bidi
Value: normal | embed | bidi-override | inherit
Initial: normal
Applies to: 所有元素,但请参阅正文
Inherited: no
Percentages: N/A
Media: 视觉
Computed value: 按指定计算

此属性的值具有以下含义:

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双向算法的实现后的顺序相同。在此过程中,具有'display: inline'的替换元素被视为中性字符,除非其'unicode-bidi'属性的值不是'normal',在这种情况下,它们将按照为元素指定的'direction'视为强字符。所有其他原子内联级框始终被视为中性字符。

请注意,为了能够以统一的方向流动内联框(完全从左到右或完全从右到左),可能需要创建更多的内联框(包括匿名内联框),并且在流动之前可能需要分割和重新排序某些内联框。

由于Unicode算法的嵌入级别限制为61级,因此在适当情况下应谨慎使用除'normal'以外的'unicode-bidi'值。特别是,'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,样式表负责设置书写方向。这是样式表:

/* 双向规则 */
HEBREW, HE-QUO  {direction: rtl; unicode-bidi: embed}
ENGLISH         {direction: ltr; unicode-bidi: embed}

/* 显示规则 */
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的第一个音节可能适合上一行,但通常会抑制在从右到左的上下文中对从左到右单词的连字符断字,反之亦然,以避免在行中间显示连字符。