17

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

17 表格

17.1 表格简介

    表格代表了数据间的关系。作者在文档语言中指定这些关系,并在CSS中以两种方式指定其呈现:视觉的和听觉的。

    作者可以指定一个表格的视觉格式为单元格组成的长方形栅格。单元格的行与列可以组织成行组和列组。行、列、行组、列组以及单元格可以在其周围有边框(CSS2中有两种边框模型)。作者可以在一个单元格中水平或垂直对齐数据,也可以在一行或一列中所有单元格中对齐数据。

    作者也可以指定表格的听觉呈现:表头和数据将如何说出。在文档语言中,作者可以标记单元格和单元格组以做听觉渲染,单元格的头将在单元格数据之前说出。效果就是,这将“序列化”该表格:用户用听觉方式浏览表格时听到的是一系列表头,随后是数据。

    下面是HTML 4.0中描述的一个3行3列的简单表格:

<TABLE>
<CAPTION>This is a simple 3x3 table</CAPTION>
<TR id="row1">
   <TH>Header 1      <TD>Cell 1        <TD>Cell 2
<TR id="row2">
   <TH>Header 2      <TD>Cell 3        <TD>Cell 4
<TR id="row3">
   <TH>Header 3      <TD>Cell 5        <TD>Cell 6
</TABLE>

    该代码创建了一个表格(TABLE元素),三行(TR元素),三个表头单元格(TH元素)以及六个数据单元格(TD元素)。注意,这个例子中三列的指定是隐式的:表头和数据单元格需要多少列,就有多少列。

    下面的CSS规则将表头单元格中的文本在水平方向居中对齐,并以粗体文字呈现数据:

TH { text-align: center; font-weight: bold }

    下一条规则将表头文本在垂直方向对齐其基线,而数据单元格垂直居中:

TH { vertical-align: baseline }
TD { vertical-align: middle }

    下一条规则指定第一行的边框是3px宽的实心蓝色边框,而其它的则是1px宽的实心黑色边框:

TABLE   { border-collapse: collapse }
TR#row1 { border-top: 3px solid blue }
TR#row2 { border-top: 1px solid black }
TR#row3 { border-top: 1px solid black }

    注意,行边框在行相遇的地方是互相交迭的。那么第一行和第二行间的边框应该是什么颜色(黑的还是蓝的)?多少宽(1px还是3px)?我们将在解决边框冲突一节中加以讨论。

    下面的规则将表格的标题放置在表格之上:

CAPTION { caption-side: top }

    最后,下面的规则规定,一旦需要听觉渲染,每行数据应该读成“头,数据,数据”:

TH { speak-header: once }

    例如,第一行将读成:“Header1 Cell1 Cell2”。反过来,如果是如下的规则:

TH { speak-header: always }

它就应该读成“Header1 Cell1 Header1 Cell2”。

    上面的例子展示了CSS如何与HTML 4.0元素协同;在HTML 4.0中,不同表格元素(TABLE,CAPTION,THEAD,TBODY,TFOOT,COL,COLGROUP,TH以及TD)的语义定义非常明确。在其它文档语言中(如XML应用),可能没有预定义的表格元素。因此CSS2允许作者“映射”文档语言元素到表格元素,通过'display'属性。例如,下面的规则使FOO元素表现如同HTML的TABLE元素而BAR元素如同CAPTION元素:

FOO { display : table }
BAR { display : table-caption }

    我们将在一下各节讨论各种表格元素。本规范中,术语表格元素指的是任何参与到表格创建的元素。而“内部”表格元素是指产生行、行组、列、列组或单元格的元素。

17.2 CSS的表格模型

    CSS表格模型基于HTML 4.0表格模型,表格的结构非常接近表格的视觉布局。该模型中,表格包含一个可选的标题以及任意行的单元格。表格模型通常称为“行优先”,因为作者在文档语言中显式地指定行而不是列。一旦所有的行被指定,列就可以被派生出来:每行中第一个单元格属于第一列,第二个属于第二列,等等。行与列可以在结构上被分组,并反应到呈现中(例如,在一组行的周围可能画上一个边框)。

    因此,表格模型包含了表格,标题,行,行组,列,列组以及单元格。

    CSS模型并不要求文档语言包含对应这些元素中每一个的元素。对于某些文档语言(如XML应用),并没有预定义的表格元素,因此作者必须建立文档语言元素到表格元素的映射。这是通过'display'属性完成的。如下的'display'取值将表格语义分配给一个任意元素:

table(HTML:TABLE)
指定了一个元素,定义了一个块级表格:它是一个长方形的块,并参与块格式化内容
inline-table(HTML:TABLE)
指定了一个元素,定义了一个行内表格:它是一个长方形的块,并参与行内格式化内容
table-row(HTML:TR)
指定一个元素为单元格组成的行。
table-row-group(HTML:TBODY)
指定一个元素将一行或多行分组。
table-header-group(HTML:THEAD)
类似'table-row-group',但是对于视觉格式化而言,行组总在所有其它行、其它行组前显示,但在任何顶置标题之后显示。用户端在打印时可能在表格延展的每页都重复打印脚注行。
table-footer-group(HTML:TFOOT)
类似'table-row-group',但是对于视觉格式化而言,该行组总在所有其它行、其它行组之后显示,但在任何底置标题之前显示。用户端在打印时可能在表格延展的每页都重复打印脚注行。
table-column(HTML:COL)
指定一个元素描述了单元格列。
table-column-group(HTML:COLGROUP)
指定一个元素将一列或多列分组。
table-cell(HTML:TD,TH)
指定一个元素代表了一个单元格。
table-caption(HTML:CAPTION)
指定了表格的标题。

    如果一个元素的'display'设置为'table-column'获'table-column-group',它不会被渲染(就象被设置为'display: none'一样),但是它们还是有用的,因为它们可能有些属性会给它们所代表的列引入某些特定的样式。

    附录中的HTML 4.0缺省样式表展示了这些值在HTML 4.0中的应用:

TABLE    { display: table }
TR       { display: table-row }
THEAD    { display: table-header-group }
TBODY    { display: table-row-group }
TFOOT    { display: table-footer-group }
COL      { display: table-column }
COLGROUP { display: table-column-group }
TD, TH   { display: table-cell }
CAPTION  { display: table-caption }

    用户端可以忽略这些'display'属性值,因为作者不应该改变一个元素被期望的行为。

17.2.1 匿名表格对象

    非HTML的文档语言可能不包含CSS2表格模型中所有的元素。在这种情况下,必须假定那些“缺失”的元素,以便表格模型可以工作。缺失的元素将产生匿名对象(例如,视觉表格布局中的匿名框)。其参照的规则如下:

  1. 任何表格元素将自动产生必要的匿名表格对象包围自身,其中包含至少三个嵌套对象来对应一个'table'/'inline-table'元素,一个'table-row'元素和一个'table-cell'元素。
  2. 如果'table-cell'元素T的父元素P不是'table-row',在P/T之间会产生一个对应于'table-row'的对象。该对象将扩展到所有后继的T的(文档树中的)兄弟'table-cell'。
  3. 如果'table-row'元素T的父元素P不是'table','inline-table'或'table-row-group'元素,在P/T之间会产生一个对应于'table'的对象。该对象将扩展到所有后继的T的(文档树中的)兄弟,只要它们需要一个'table'父元素:'table-row','table-row-group','table-header-group','table-footer-group','table-column','table-column-group'以及'caption'。
  4. 如果'table-row-group'(或者'table-header-group'、'table-footer-group')元素T的父元素不是'table'或'inline-table',在P/T之间会产生一个对应于'table'元素的对象。该对象将扩展到所有后继的T的(文档树中的)兄弟,只要它们需要一个'table'父元素:'table-row','table-row-group','table-header-group','table-footer-group','table-column','table-column-group'以及'caption'。
  5. 如果'table-row'元素P的子元素T不是'table-cell'元素,在P/T之间会产生一个对应于'table-cell'元素的对象。该对象将扩展到所有后继的T的兄弟,只要它们不是'table-cell'元素。

    下面的XML例子中,假定'table'元素包含HBOX元素:

<HBOX>
  <VBOX>George</VBOX>
  <VBOX>4287</VBOX>
  <VBOX>1998</VBOX>
</HBOX>

    因为相关联的样式表是:

HBOX { display: table-row }
VBOX { display: table-cell }

    下面的例子中,为了包含ROW中的文字,假定了三个'table-cell'元素。注意,文字会进一步被包含在行间框中,正如可视化格式模型中描述的那样:

<STACK>
  <ROW>This is the <D>top</D> row.</ROW>
  <ROW>This is the <D>middle</D> row.</ROW>
  <ROW>This is the <D>bottom</D> row.</ROW>
</STACK>

    样式表为:

STACK { display: inline-table }
ROW   { display: table-row }
D     { display: inline; font-weight: bolder }

    根据如上规则,HTML用户端并未被要求创建匿名对象。

17.3 列选择子

    单元格可能属于两种上下文:行和列。但是,在源文件总,单元格是行的派生,而不是列的派生。但是,通过设置列的属性还是可以影响单元格的某些方面。

    下面的属性适用于列和列组元素:

'border'
只有当表格元素的'border-collapse'设置为'collapse'时,才适用列的各个边框属性。在这时,设置在列以及列组上的边框会通过解决边框冲突算法从而最终选定每个单元格边界的边框。
'background'
background属性设置了列中单元格的背景,但是只有单元格和行设置了透明背景时适用。参见“表格的层和透明性”
'width'
'width'属性给出了列的最小宽度。
'visibility'
如果设置一个列的'visibility'为'collapse',那么该列中所有的单元格都不会被渲染,而延伸到其它列的单元格将被剪裁。另外,表格的宽度也会相应减少该列本应占据的宽度。参见“动态行列效果”。其它'visibility'的取值没有效果。

    下面给出了一些设置列属性的样式规则的范例。头两个规则一起实现了HTML 4.0的“规则”属性,取值为"cols"。第三个规则使"totals"列成为蓝色,最后两个规则展示如何使一列的宽度固定,是通过使用固定表格布局算法实现的。

COL   { border-style: none solid }
TABLE { border-style: hidden }
COL.totals { background: blue }
TABLE { table-layout: fixed }
COL.totals { width: 5em }

17.4 可视化格式模型中的表格

    在所谓的可视化格式模型中,表格可以表现为一个块类或被替换的行内元素。表格有内容,边白,边框和边距。

    不论哪种情形,表格元素将产生一个匿名框来包含表格框本身和标题框(如果有的话)。表格和标题框包含自身的内容,边白,边距和边框区域。该长方形匿名框的尺寸是能包含两者的最小尺寸。垂直边距在表格框和标题框相交处重合。表格的任何重定位都必须移动整个匿名框,而不仅仅是表格框,从而标题将跟随表格移动。

A table with a caption aboveit; both have margins and the margins between them are collapsed, asis normal for vertical margins.   [D]

上方有标题的表格示意图。标题的底边距与表格的顶边距重合。

17.4.1 标题定位和对齐

'caption-side'
取值:   top | bottom | left | right | inherit
初始值:   top
适用于:   'table-caption'元素
可否继承:  
百分比:   N/A
媒介:   视觉

    该属性指定标题框相对表格框的为止。取值的含义如下:

top
标题框在表格框的上方。
bottom
标题框在表格框的下方。
left
标题框在表格框的左方。
right
标题框在表格框的右方。

    'table'元素之上或之下的标题格式化时就好像它们是表格之前或之后的一个块元素一样,除了(1)它们继承表格的可继承属性,(2)如果表格之前有任何'compact'或'run-in'元素,它们并不被认为是一个块框。

    在一个表格框上或下的标题也表现为一个块框而参与宽度计算;它的宽度计算要参考表格框包含块的宽度。

    另一方面,如果标题在表格框的左边或右边,如果'width'的取值不是'auto'则将显式地设置宽度,而'auto'告诉用户端选择一个“合理的宽度”。这可能从“最窄可能的框”到“一条线”,因此我们建议对于左右标题的宽度,不要设置'auto'。

    要将标题内容在标题框中水平对齐,可以使用'text-align'属性。对于左右标题在表格框中的垂直对齐,使用'vertical-align'属性。在这种情况,唯一有意义的取值是'top','middle'以及'bottom'。其它的取值都视同为'top'。

    本例中,'caption-side'属性将标题放置在表格底部。标题的宽度和表格父元素宽度相同,标题文本将左对齐。

CAPTION { caption-side: bottom; 
          width: auto;
          text-align: left }

    下面的例子展示如何将标题放置在左边距中。通过设置左右边距为'auto',表格本身是居中的,而整个包含表格和标题的框位移到左边界,距离和标题的宽度相同。

BODY {
    margin-left: 8em
}
TABLE {
    margin-left: auto;
    margin-right: auto
}
CAPTION {
    caption-side: left;
    margin-left: -8em;
    width: 8em;
    text-align: right;
    vertical-align: bottom
}

    假定表格的宽度小于可用宽度,格式化的结果可能类似于这样:

A centered table with acaption in the left margin of the page   [D]

该图显示作为负的'margin-left'属性取值,表格居中,标题延伸到左边距。

17.5 表格内容的可视布局

    如同其它文档语言的元素,表格内部元素产生矩形,有内容、边白和边框。但是它们没有边距。

    这些框的可视布局受一个矩形及不规则行列栅格的控制。每个框占据一些栅格单元格,而这是由如下规则确定的。这些规则不适用于HTML 4.0或更早的版本;HTML也事实它本身关于行列扩展的限制。

  1. 每个行框占据一行的栅格单元格。这些行框在一起以它们在源文档中出现的顺序自顶至底填充表格(也就是说,表格占据和行元素数量一样多的栅格行)。
  2. 行组占据它包含的行占据的栅格单元格。
  3. 列框占据一个或多个栅格单元格列。列框按照它们出现的顺序挨个排列。第一列可能是在左边也可能是在右边,这取决于表格的'direction'属性。
  4. 列组占据它包含的列占据的栅格单元格。
  5. 单元格可以扩展到若干行或列。(尽管CSS2并未定义行列扩展的数目如何定义,但是用户端对源文档可能有特别的了解;以后版本的CSS也许会提供以CSS语法表述的这一规则。)每个单元格因此是一个举行框,宽度和高度为一个或多个栅格单元格。该矩形的顶行是该单元格父指定的行。该矩形必须尽可能靠左,但是不可以覆盖任何其它单元格框,并在源文档同行的所有其它单元格之右。(该约束仅当表格的'direction'属性为'ltr'时适用;如果'direction'为'rtl',只要将上文中的“左”、“右”互换即可。)
  6. 单元格框不可以延伸超出表格或行组的最后一个行框;用户端必须将其缩短直到它合适为止。

注意:单元格可以相对或绝对定位,但是不建议这么做:定位和浮动将框从流中移出,从而影响表格的对齐。

    这里有两个例子。第一个我们假定在HTML文档中:

<TABLE>
<TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4
<TR><TD colspan="2">5
</TABLE>
<TABLE>
<ROW><CELL>1 <CELL rowspan="2">2 <CELL>3 <CELL>4
<ROW><CELL colspan="2">5
</TABLE>

    第二个表格格式化结果如右图所示。然而,HTML表格的渲染并未被HTML显式定义,CSS也不尝试去定义之。用户端可以自由渲染之,例如象左图显示的那样。

One table with overlappingcells and one without   [D]

左图显示一个有错误的HTML 4.0表格的一种可能的渲染;右图是类似的一个非HTML表格唯一可能的渲染。

17.5.1 表格的层和透明性

    为了确定每个单元格的背景,不同的表格元素可以被理解为处在一个六个层次的层面上。在一个层上设置的元素的背景只有当它上面的层都是透明背景时才可见。

schema of table layers   [D]

表格层规划

  1. 最底层是一个单一平面,代表表格框本身。与所有框类似,它可以是透明的。

  2. 上一层包含列组。列组与表格同高,但不一定水平覆盖整个表格。

  3. 列组之上是代表列框的区域。和列组类似,列与表格同高,但不一定水平覆盖整个表格。

  4. 上一层包含行组。每个行组与表格同宽。加在一起,行组自顶向下完全覆盖整个表格。

  5. 倒数第二层包含行。行也覆盖整个表格。

  6. 最顶层包含单元格。如图所示,尽管所有的行包含同样数量的单元格,但不是每个单元格都有特定的内容。这些“空”的单元格是透明的,可以让更底层的透出来。

    下例中,第一行有四个单元格,第二行没有单元格,因此可以看到表格背景,除了有一个单元格从第一行扩展到该行。下面的HTML代码和样式表规则:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
  <HEAD>
    <STYLE type="text/css">
      TABLE { background: #ff0; border-collapse: collapse }
      TD    { background: red; border: double black }
    </STYLE>
  </HEAD>
  <BODY>
    <P>
    <TABLE>
      <TR>
        <TD> 1 
        <TD rowspan="2"> 2
        <TD> 3 
        <TD> 4 
      </TR>
      <TR><TD></TD></TR>
    </TABLE> 
  </BODY>
</HTML>

可能被格式化成这样:

Table with three empty cellsin bottom row   [D]

最底行有三个空白单元格的表格

17.5.2 表格宽度算法:'table-layout'

    CSS并未定义所谓的“优化”的表格布局,因为在很多情况下,什么是优化纯粹是个品味问题。CSS确实定义了一些约束,用户端在表格布局时必须遵守。用户端可以适用任何它们想用的算法,而且除非在“固定布局算法”下,可以自由选择优先速度还是优先精度。

'table-layout'
值: auto | fixed | inherit
初始值: auto
适用于: 'table'及'inline-table'元素
可否继承:
百分比: N/A
媒介: 视觉

    'table-layout'属性控制了布局表格单元格、行、列的算法。取值的含义如下:

fixed
适用固定表格布局算法
auto
适用任何表格布局算法

    这两种算法分别描述如下。

固定表格布局

    适用这种(快速)算法,表格的水平布局不依赖于单元格的内容;而只依赖于表格的宽度,列的宽度以及边框或单元格的间隔。

    表格的宽度可以显式的由'width'属性指定。如果取值为'auto'(对于'display: table'和'display: inline-table')意味着使用自动表格布局算法。

    在固定表格布局算法中,每个列的宽度是这样确定的:

  1. 如果列元素的'width'属性取值不是'auto',那么该列的宽度为该指定值。
  2. 否则,行中第一个单元格若其'width'属性不是'auto',则设定了该列的宽度。如果单元格扩展到若干个列,宽度将在列内平分。
  3. 其它列平均分配剩下的表格水平空间(减去边框或单元格间隔)。

    因此,表格的宽度将是表格元素'width'属性值和列宽(加上单元格间隔或边框)和的较大值。如果表格比列宽,多余的空间将分配到所有列中。

    在这种情况下,用户端在收到整个第一行后就可以开始表格布局。后续行的单元格不影响列宽。如果单元格内容有溢出,经根据'overflow'属性确定是否建材溢出的内容。

自动表格布局

    在本算法中(一般要求不超过两次解析),表格的宽度由列宽(以及间隔的边框)给出。本算法代表了本规范写就时若干常见HTML用户端的行为。如果'table-layout'为'auto',UA并不被要求实施该算法来确定表格布局;它们可以使用任何其它算法。

    该算法可能不那么有效率因为它要求用户端在确定最终布局前获得所有的表格内容,并可能要求多于一次的解析。

    列宽是这样来确定的:

  1. 计算每个单元格的最小内容宽度(MCW):经格式化的内容可以扩展到好几行,但是不可以溢出单元格框。如果指定的单元格'width'(W)大于MCW,W将作为最小单元格宽度。'auto'意味着MCW为最小单元格宽度。

    另外,计算每个单元格的“最大”单元格宽度:除非有显式的分行,将内容不分行的进行格式化。

  2. 对于每一列,根据只占该列的那些单元格,确定一个最大和最小的列宽。最小值是其MCW最大的那个单元格的宽度(或列的'width',取较大的)。最大值是起最大单元格宽度最大的单元格宽度(或列的'width',取较大的)。
  3. 对于扩展到若干个列的每个单元格,增加这些列的最小宽度,使得这些列宽加在一起至少和单元格同宽。对于最大宽度也照样处理。如果可能的话,每个扩展到的列增加的宽度应大致相同。

    这样对于每个列就得到了最大和最小宽度。列宽是这样影响最终表格的宽度的:

  1. 如果'table'或'inline-table'元素的'width'属性不是'auto',而是指定值(W),该属性的计算值应该是这两者的较大值:W,以及所有列要求的最小宽度加上单元格间隔或边框(MIN)。如果W大于MIN,那么多余的宽度将分配到各列中去。
  2. 如果'table'或'inline-table'元素设置了'width: auto',那么计算得到的表格宽度应为这两者的较大值:MIN,以及表格包含块的宽度。然而,如果列加上单元格间隔或边框要求的最大宽度(MAX)小于包含块的宽度,使用MAX。

    列宽如果是百分比,则相对于表格宽度。如果表格设置了'width: auto',那么百分比表示了列宽的约束,UA应该尝试满足该约束。(很显然,这并总是可能的:如果列宽是'110%',那么该约束是无法满足的。)

注意:在该算法中,行(及行组)和列(及列组)都约束了也受约束于它们包含的单元格的尺寸。设置列宽可能间接影响了行高,反之亦然。

17.5.3 表格高度算法

    表格的高度由'table'或'inline-table'的'height'给出。如果取值为'auto'则意味着高度是行高加上单元格间隔或边框的综合。任何其它取值将显式指定高度;因而表格可能比其行高来的高或低。如果表格高度和内容高度不一致,CSS2并未指定渲染方法,特别是未说明内容高度是否应超越指定的高度:如果表格高度大于内容高度,多余的行高应如何分配;或者反过来,如果内容高度大于指定的表格高度,UA是否应该提供滚动机制。注意:将来版本的CSS可能会指定这个。

    一旦UA获得行内所有单元格,就可以计算'table-row'元素框的高度:它是行内指定的'height'最大值和单元格要求的最小高度(MIN)的较大者。如果'table-row'的'height'取值为'auto',则意味着计算出的高度应为MIN。MIN取决于单元格框高度和单元格框的对齐(很类似于线框的高度计算)。如果指定表格行和行组'height'的百分比,CSS2并未定义该百分比应参照哪个高度。

    CSS2中,一个单元格框的高度应是表格单元格'height'属性和内容所需最小高度(MIN)中较大的值。如果'height'取值为'auto'就意味着计算值为MIN。单元格'height'如果指定为百分比,CSS2并未定义该百分比应参照哪个高度。

    CSS2也没有指定如果单元格扩展到若干行的话,会如何影响高度的计算,除了这点:行高的和应该足够大而可以包容扩展到若干行的单元格。

    每个单元格的'vertical-align'属性决定了在行内的对齐方式。每个单元格内容都有一个基线,一个顶线、中线和底线。这点和行类似。在表格上下文中,'vertical-align'的取值含义如下:

baseline
单元格基线和它所扩展的行中第一行的基线一样高(关于单元格和行的基线的定义参见下文)。
top
单元格框的顶线和它所扩展的行中第一行的顶线一样高。
bottom
单元格框的底线和它所扩展的行中最后一行的底线一样高。
middle
单元格的中线和它扩展的行的中线一样高。
sub, super, text-top, text-bottom
这些值对单元格不适用;单元格采用基线对齐。

    单元格的基线是单元格中第一个线框的基线。如果没有文本,那么基线就是该单元格中显示的无论什么对象的基线;如果没有任何对象,那么就取单元格框的底线。所有设置了'vertical-align: baseline'的单元格中,单元格框顶到基线的最大距离将用来设置行的基线。请看下例:

Example of verticallyaligning the cells   [D]

图形显示单元格不同的'vertial-align'取值的效果

    单元格框1和2基于基线对齐。单元格框2在基线上的高度最高,因此就决定了该行的基线。注意,如果没有单元格框基于基线对齐,那么该行就没有(也不需要)基线。

    为了避免歧义,单元格的对齐按照如下顺序进行:

  1. 首先,基于基线对齐的单元格得到定位。这样就可以得到该行的基线。接着,定位'vertical-align: top'的单元格。
  2. 现在,该行有了一个顶线、也可能有了基线,以及一个临时的高度——是当前定位的单元格顶到最低的底的距离。(参见下面的单元格边白条件。)
  3. 如果任何其它单元格,其对齐方式是底线或中线,而其高度比目前的行高要大,该行的高度将通过降低底线的方式来达到这些单元格中最大的高度。
  4. 最后,定位这些其它的单元格。

    如果单元格框的高度小于行高,那么它将获得额外的顶或底边白。

17.5.4 列内的水平对齐

    单元格内容的水平对齐由'text-align'属性指定。

    如果一列中若干个单元格的'text-align'属性设置为一个<string>值,这些单元格将对齐于一个垂直轴线。字符串的开始会接触该轴。字符方向确定了字符串安放在轴的左边还是右边。

    这样对齐文本只有在文本可以在一行中显示时才游泳。如果单元格内容有多行,那么结果是未被定义的。

    如果一个单元格的'text-align'取值为一个字符串,但是该字符串并问出现在单元格内容中,那么单元格内容的结尾接触对齐的垂直轴。

    这些字符串不一定每个单元格都相同,尽管通常是如此的。

    CSS并未提供一种方法来指定垂直对齐轴相对于列框边的偏移。

    以下的样式表:

   TD { text-align: "." }
   TD:before { content: "$" }

    将使下面HTML表格中的这些钱数列:

  <TABLE>
  <COL width="40">
  <TR> <TH>Long distance calls
  <TR> <TD> 1.30
  <TR> <TD> 2.50
  <TR> <TD> 10.80
  <TR> <TD> 111.01
  <TR> <TD> 85.
  <TR> <TD> 90
  <TR> <TD> .05
  <TR> <TD> .06
  </TABLE>

对齐小数点。为了好玩,我们用了:before伪元素在每个数字前插入美元符号。表格可能被渲染成这样:

Long distance calls
              $1.30      
              $2.50
             $10.80
            $111.01
             $85.
             $90
               $.05
               $.06

17.5.5 动态行列效果

    行、行组、列、列组的'visibility'属性可以取值为'collapse'。它使得整个行或列被移出显示,而这些行列通常要占用的位置为其它内容所用。但是,行列的禁止显示并不影响表格的布局。考虑到列约束可能的改变,这就允许动态的移除表格行列的效果而不用强迫重新表格布局。

17.6 边框

    CSS中有两种完全不同的方法设置单元格的边框。一种最适合于在独立的单元格中设置所谓的分离边框,另一种适合设置从表格一端到另一端的连续边框。很多边框样式在两个方法中都可以实现,所以用哪个基本上是个偏好问题。

'border-collapse'
值: collapse | separate | inherit
初始值: collapse
适用于: 'table'及'inline-table'元素
可否继承:
百分比: N/A
媒介: 视觉

    该属性选择了表格边框模型。取值为'separate'将选择分离边框模型。取值'collapse'选择重合的边框模型。分别讨论如下。

17.6.1 分离的边框模型

'border-spacing'
值: <length> <length>? | inherit
初始值: 0
适用于: 'table'及'inline-table'元素
可否继承:
百分比: N/A
媒介: 视觉

    长度指定了分割相邻单元格边框的距离。如果指定一个长度,就指定了水平和垂直的间距。如果给出两个长度,第一个指定水平间距,而第二个指定垂直间距。长度不可以是负数。

    这种模型中,每个单元格有一个独立的边框。'border-spacing'属性指定了相邻单元格边框间的距离。该空间由表格元素的背景填充。行、列、行组和列组不可以有边框(也就是说,用户端必须忽略这些元素的边框属性)。

    下图中的表格可能是如下这个样式表的结果:

  TABLE      { border: outset 10pt; 
               border-collapse: separate;
               border-spacing: 15pt }
  TD         { border: inset 5pt }
  TD.special { border: inset 10pt }  /* The top-left cell */

A table withborder-spacing   [D]

一个表格的'border-spacing'设置为长度值。注意每个单元格有自己的边框,而表格也有自己的边框。

空单元的边框:'empty-cells'属性

'empty-cells'
值: show | hide | inherit
初始值: show
适用于: 'table-cell'elements
可否继承:
百分比: N/A
媒介: 视觉

    在分离边框模型中,该属性控制了没有可视内容的单元格周围边框的渲染。空单元格以及'visibility'属性为'hidden'的单元格都被认为是没有可视内容。可视内容包括"&nbsp;"以及其它空白,除了ASCII CR("\0D"),LF("\0A"), tab("\09")和空格("\20")。

    如果该属性取值为'show',空白单元格周围会画出边框(和一般的单元格一样)。

    取值为'hide'意味着在空单元格周围不画边框。更进一步说,如果一行中所有单元格该属性取值都为'hide'而且都没有任何可视内容,那么整行就视同设置了'display: none'一样。

    下面的规则使所有的单元格周围都要画出边框:

TABLE { empty-cells: show }

17.6.2 重合的边框模型

    在重合的边框模型中,有可能指定一个边框来围绕单元格、行、行组、列、列组的全部或部分。HTML的"rule"属性可以用这种方式来指定。

    边框定位在单元格间的栅格线中心。用户端必须找到一个统一的规则来取整处理间距为奇数单位(屏幕像素点,打印机点阵等)的情况。

    下面的图形显示了表格宽度、边框宽度、边白以及单元格是如何交互的。它们的关系由下式给出,对表格的每一行都适用:

row-width = (0.5 * border-width0) +padding-left1 + width1 +padding-right1 +border-width1 +padding-left2 +...+padding-rightn +(0.5 * border-widthn)

    这里的n代表行内单元格的数量,而border-widthi代表单元格i和i + 1间的边框。注意,两个最外的边框只有一半计入表格宽度。其它一半算在边距区域中。

Schema showing the widths ofcells and borders and the padding of cells   [D]

显示单元格、边框以及单元格边白的图形。

    注意,在该模型中,表格的宽度包含表格边框的一半。同时,本模型中,表格并没有边白(但是有边距)。

解决边框冲突

    在重合边框模型中,每个单元格每条边上的边框可能被在那条边上相遇的各类元素(单元格,行,行组,列,列组以及表格本身)的边框属性指定,而这些边框的宽度、样式、颜色都可能不相同。准则就是:在每条边上,最最“吸引眼球”的边框样式被选中,除非出现了任何一个'hidden'样式从而无条件的将边框关闭了。

    下面的规则说明在有冲突的情况下,该选择哪个边框样式:

  1. 边框如果其'border-style'为'hidden',那么它的优先级高于任何其它相冲突的边框。任何边框只要有该取值,将抑制该位置的所有边框。
  2. 边框如果其属性中有'none',那么它的优先级是最低的。只有在该边汇集的所有元素的边框属性都是'none',该边框才会被省略(不过请注意,'none'是边框样式的缺省值。)
  3. 如果没有哪个样式为'hidden',而且至少有一个不是'none',那么相比更宽的边框,相对较窄的边框会被忽略。如果若干个边框的'border-width'一样,那么样式的优先次序如下:'double','solid','dashed','dotted','ridge','outset','groove',和最低的:'inset'。
  4. 如果边框样式只有颜色上的区别,那么单元格的样式优先,然后是行的,行组的,列的,列组的,最后是表格的。

    下面的例子演示了上述规则的应用。样式表如下:

  TABLE          { border-collapse: collapse;
                   border: 5px solid yellow; }
  *#col1         { border: 3px solid black; }
  TD             { border: 1px solid red; padding: 1em; }
  TD.solid-blue  { border: 5px dashed blue; }
  TD.solid-green { border: 5px solid green; }

    HTML源文件:

<P>
<TABLE>
<COL id="col1"><COL id="col2"><COL id="col3">
<TR id="row1">
    <TD> 1
    <TD> 2
    <TD> 3
</TR>
<TR id="row2">
    <TD> 4 
    <TD class="solid-blue"> 5
    <TD class="solid-green"> 6
</TR>
<TR id="row3">
    <TD> 7
    <TD> 8
    <TD> 9
</TR>
<TR id="row4">
    <TD> 10
    <TD> 11
    <TD> 12
</TR>
<TR id="row5">
    <TD> 13
    <TD> 14
    <TD> 15
</TR>
</TABLE>

    可能产生如下的效果:

An example of a table with collapsed borders   [D]

重合边框模型中的一个表格范例。

    下面这个例子显示了一个表格,其行间有分隔线。表格的顶边框设置为'hidden'而抑制了第一行的顶边框。这就实现了HTML 4.0中的"rules"属性(rules="rows")。

TABLE[rules=rows] TR { border-top: solid }
TABLE[rules=rows]    { border-collapse: collapse; 
                       border-top: hidden }

Table with horizontalrules    [D]

带有行间水平分隔线的表格。

    本例中,不设置TABLE的'hidden'边框也可以达到同样的效果,只要对第一行独立设置即可。喜欢用哪个方法纯粹是喜好问题。

TR:first-child { border-top: none }
TR { border-top: solid }

    下面是另一个例子展示隐藏重合的边框:

Tablewith two omitted borders   [D]

表格带有两个省略的内部边框。

    HTML源文件:

<TABLE style="border-collapse: collapse; border: solid;">
<TR><TD style="border-right: hidden; border-bottom: hidden">foo</TD>
    <TD style="border: solid">bar</TD></TR>
<TR><TD style="border: none">foo</TD>
    <TD style="border: solid">bar</TD></TR>
</TABLE>

17.6.3 边框样式

    某些'border-style'的取值在表格中的含义和在其它元素中的含义不同。下表中以星号标明。

none
没有边框。
*hidden
等于'none',但是在重合边框模型中会同时抑制其它边框(参见解决边框冲突conflicts一节)。
dotted
边框是一系列的点。
dashed
边框是一系列的短线。
solid
边框是一条实线。
double
边框是双实线。两条线及只见空白的距离之和等于'border-width'的值。
groove
边框看起来象是嵌入绘画平面。
ridge
和'grove'相反:边框看起来象是突出于绘画平面。
*inset
分离边框模型中,边框使整个框看起来象是嵌入绘画平面。在重合边框模型中,等于'groove'。
*outset
分离边框模型l中,边框使整个框看起来象是突出于绘画平面。在重合边框模型中,等于'ridge'。

17.7 表格的音频渲染

    如果表格通过一个语音产生器说出,数据单元格和头单元格之间的关系必须以不同于水平和垂直对齐的方式说出。有些语音浏览器可能允许用户以二维的方式在表格中移动,因而给予它们对应以空间表示的关系的可能。如果这是可能的,样式表必须指出头要在哪个点上说出。

17.7.1 表头的叙述:'speak-header'属性

'speak-header'
值: once | always | inherit
初始值: once
适用于: 有表格头元素信息的元素
可否继承:
百分比: N/A
媒介: 音频

    该属性指定表格头是否在每个单元格前说出,或只是在某个单元格关联的头与前一个不同时说出。取值的含义如下:

once
头只说一次,在一系列单元格之前。
always
头在相关的单元格前说出。

    每个文档语言可能有不同的机制允许作者指定头。例如,在HTML 4.0([HTML40])中,可以有三种不同的属性来指定头信息("headers","scope"以及"axis")。如果这些属性没有被指定,本规范提供了一种算法来确定头信息。

Image of a table created in MSWord   [D]

带有头单元格的表格图形("SanJose"和"Seattle"),但不在它们适用的数据的同一行或列。

    这个HTML例子演示了在两个地点(San Jose和Seattle)连续若干天花费在食品、住宿和交通方面的费用。理论上说,你可以将这个表想象为N维的。这些维数包括:地点,日期,类别以及小计。某些单元格定义了一个轴上的标记,而其它一些给出了在该空间内某点上花费的金钱。这个表格的源文件如下:

<TABLE>
<CAPTION>Travel Expense Report</CAPTION>
<TR>
  <TH></TH>
  <TH>Meals</TH>
  <TH>Hotels</TH>
  <TH>Transport</TH>
  <TH>subtotal</TH>
</TR>
<TR>
  <TH id="san-jose" axis="san-jose">San Jose</TH>
</TR>
<TR>
  <TH headers="san-jose">25-Aug-97</TH>
  <TD>37.74</TD>
  <TD>112.00</TD>
  <TD>45.00</TD>
  <TD></TD>
</TR>
<TR>
  <TH headers="san-jose">26-Aug-97</TH>
  <TD>27.28</TD>
  <TD>112.00</TD>
  <TD>45.00</TD>
  <TD></TD>
</TR>
<TR>
  <TH headers="san-jose">subtotal</TH>
  <TD>65.02</TD>
  <TD>224.00</TD>
  <TD>90.00</TD>
  <TD>379.02</TD>
</TR>
<TR>
  <TH id="seattle" axis="seattle">Seattle</TH>
</TR>
<TR>
  <TH headers="seattle">27-Aug-97</TH>
  <TD>96.25</TD>
  <TD>109.00</TD>
  <TD>36.00</TD>
  <TD></TD>
</TR>
<TR>
  <TH headers="seattle">28-Aug-97</TH>
  <TD>35.00</TD>
  <TD>109.00</TD>
  <TD>36.00</TD>
  <TD></TD>
</TR>
<TR>
  <TH headers="seattle">subtotal</TH>
  <TD>131.25</TD>
  <TD>218.00</TD>
  <TD>72.00</TD>
  <TD>421.25</TD>
</TR>
<TR>
  <TH>Totals</TH>
  <TD>196.27</TD>
  <TD>442.00</TD>
  <TD>162.00</TD>
  <TD>800.27</TD>
</TR>
</TABLE>

    以这种方式提供数据模型,作者就使得可以发出语音的浏览器可以用非常丰富的方法来浏览这个表格,例如,每个单元格可以作为列表说出,在每个数据单元格之前重复适用的头:

  San Jose, 25-Aug-97, Meals:  37.74
  San Jose, 25-Aug-97, Hotels:  112.00
  San Jose, 25-Aug-97, Transport:  45.00
 ...

    浏览器也可以在头改变时才说出它们:

San Jose, 25-Aug-97, Meals: 37.74
    Hotels: 112.00
    Transport: 45.00
  26-Aug-97, Meals: 27.28
    Hotels: 112.00
...

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页