内容概要
本章節描述 CSS 裡表格的處理模型,其中的一部分是布局。本章節引入了兩個布局演算法 ― 第一個是固定表格布局演算法,具有完整定義,但是第二個的自動表格布局演算法在本規範中沒有完整定義。
有些廣泛使用的自動表格布局演算法的實作已經有相當接近的兼容性。
表格布局可以用來表示資料之間的列表關係。網頁作者在文件語言描述這些關係之後,可以用 CSS 2.1 指定資料的表現。
在視覺媒介中,CSS 表格可以用來產生某些布局,在這種情況下,網頁作者不該使用文件語言的表格相關元素,而應該在相關的結構元素上使用 CSS 來達到期望的布局。
網頁作者可把表格視為長方形網格來指定視覺排版。表格的行與列可以構成行群組與列群組。網頁作者可在行、列、行群組、列群組、表格單元的周圍設定邊框(CSS2.1 有兩種邊框模型)。網頁作者也可也可以讓一個表格單元中的內容垂直或水平對齊,或是對齊一行或是一列裡的所有表格單元。
Header 1 | Cell 1 | Cell 2 |
---|---|---|
Header 2 | Cell 3 | Cell 4 |
Header 3 | Cell 5 | Cell 6 |
這個代碼產生了一個表格(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: 3px solid blue } tr#row2 { border: 1px solid black } tr#row3 { border: 1px solid black }
然而,行的邊框在行與行接觸的地方有重疊。第一行與第二行中間的邊框的顏色(黑或藍)及粗細(1px 或 3px)是什麼呢?我們在解決邊框衝突小節討論這個問題。
以下規則將表格說鳴放在表格之上:
caption { caption-side: top }
前面的例子說明了怎麼在 HTML 4 元素上使用 CSS 的方法 ― 在 HTML 4 中,各種表格元素(TABLE、CAPTION、THEAD、TBODY、TFOOT、COL、COLGROUP、TH 與 TD)的語意具有完整定義。在其他文件語言(像是 XML 應用程式)不一定有預定義的表格元素,因此, CSS 2.1 讓網頁作者可以用 'display' 屬性將文件語言的元素「對應」到表格元素。舉例來說,以下規則讓 FOO、BAR 元素的行為分別與 HTML TABLE、CAPTION 元素一樣:
FOO { display : table } BAR { display : table-caption }
我們在下一個小節討論各種表格元素。在本規範中,表格元素代表任何參與表格創建的元素,內部表格元素是產生行、行群組、列、列群組或是表格單元的元素。
CSS表格模型基于HTML4表格模型,其中一个表格的结构紧密的构成该表格的可视化布局。在此模型中,一个表格由可选的标题以及任意数目的成行的单元格组成。由于编码人员在文档语言中明确的指定行(而不是列),所以表格模型被认为是“行优先”的。在所有的行都被指定完成之后才会产生列——每一行的第一个单元格属于第一列,第二个属于第二列,以此类推。行和列都可能会在结构上进行分组,这些组会反映在变现上(例如,可能会在行群组周围绘制边框)。
因此,表格模型由表格、标题、行、行群组(包括头部群组和脚部群组)、列、列群组以及单元格组成。
CSS模型不需要包括对应这些部件的元素在内的文档语言。对于没有预定义表格元素的文档语言(例如XML应用),编码人员必须映射文档语言元素到表格元素;这将需要‘display’属性。下列‘display’的值可以将表格格式化规则指派到任意元素上:
table (In HTML: TABLE)
inline-table (In HTML: TABLE)
table-row (In HTML: TR)
table-row-group (In HTML: TBODY)
table-header-group (In HTML: THEAD)
table-footer-group (In HTML: TFOOT)
table-column (In HTML: COL)
table-column-group (In HTML: COLGROUP)
table-cell (In HTML: TD, TH)
table-caption (In HTML: CAPTION)
拥有这些‘display’值的替换元素被认为是在布局时给出显示类型。举例说明,一个设置了‘display: table-cell’的图片将会填充空闲单元格控件,并且其大小可能会像普通单元格一样供表格大小算法使用。
‘display’设置为‘table-column’或‘table-column-group’的元素不会显示(正如其拥有‘display: none’),但它们是有用的,因为它们可能会拥有会影响它们所表示的列的某些样式的属性。
附录中的HTML4的默认样式表阐述了HTML4中这些值的意义:
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 }
用户代理可能会忽略HTML表格元素的这些‘display’属性值,因为HTML表格可能会为了向后兼容使用其他算法显示。但是,这不意味着阻止在HTML的其他、非表格元素上使用‘display: table’。
非 HTML 的文件語言可不含有 CSS2.1 表格模型的所有元素。在這種情況下,使用者代理必須假設「失蹤」的元素存在以讓表格模型正常運作。所有表格元素皆會在自身周圍生成必要的無名物件,使得原來的元素與無名物件至少構成三層:'table'/'inline-table' 元素、'table-row' 元素與 'table-cell' 元素。消失的元素依照下列規則生成無名物件(例如,視覺表格布局用的無名盒):
在這些規則中,我們使用下述詞彙:
行群組盒
一個 'table-row-group'、'table-header-group' 或 'table-footer-group'
真表格子盒
一個 'table-row' 盒、行群組盒、'table-column' 盒、'table-column-group' 盒或 'table-caption' 盒
真表格行父盒
一個 'table'、'inline-table' 或行群組盒
內部表格盒
一個 'table-cell' 盒、'table-row' 盒、行群組盒、'table-column' 盒或 'table-column-group' 盒
格容器
一個 'table-row' 盒或真表格行父盒
連續
若兩個兄弟盒的中間沒有僅含有空白的無名行內盒以外的兄弟,則稱這兩個兄弟為連續的。若一個兄弟盒序列裡的每一個盒都跟序列裡前面的盒連續,則稱這個兄弟盒序列為連續的。
在這些規則中,流外元素被視為是零寬度零高度的行內元素。這些元素也用同樣規則決定包含塊。
以下的步驟以三個階段進行。
在此XML实例中,由于样式表如下: HBOX { display: table-row } VBOX { display: table-cell } 所以假定‘table’元素包含HBOX元素:George 4287 1998
在下面的例子中,假定三个‘table-cell’元素包含ROW中的文本。值得注意的是,按照视觉格式化模型中的解释,文本被进一步的封装在匿名行内盒子之中:其样式表如下: STACK { display: inline-table } ROW { display: table-row } D { display: inline; font-weight: bolder } This is the
top row.This is the
middle row.This is the
bottom row.
表格单元格可能会从属于两个上下文:行和列。但是,在源文档中,单元格是行的(而不是列的)后裔。然而,另一方面,单元格会都到设置来列上的属性的影响。
下列属性被应用于列以及列群组元素上:
‘border’
‘background’
‘width’
‘visibility’
这里有一些在列上设置属性的样式规则的实例。前两个规则一起实现了HTML4中值为‘cols’的“规则”属性。第三个规则使得‘totals’列为蓝色,最后两个规则展示了如何使用固定布局算法设置一个列的固定大小。 col { border-style: none solid } table { border-style: hidden } col.totals { background: blue } table { table-layout: fixed } col.totals { width: 5em }
以視覺布局模型來說,表格可以有像是塊級元素('display: table' 的時候)或是行內級元素('display: inline-table')的行為。
表格在這兩種情況都會產生一個稱為表格包裹盒的主塊盒,表格包裹盒裡包有表格盒與所有表格說明盒(以文件順序)。表格盒是包有表格裡各內部表格盒的塊級盒。表格說明盒是擁有自己內容、邊距、邊界、邊框區域的塊級盒,且使用者代理會在表格包裹盒中把表格說明盒當作一般塊盒渲染。下面描述的 'caption-side' 屬性決定了表格說明盒的配置在表格盒的前面還是後面。
若表格為塊級,則表格包裹盒是一個 'block' 盒,若表格為行級,則表格包裹盒是一個 'inline-block' 盒。表格包裹盒建立塊格式化上下文。使用者代理會使用表格盒(而不是表格包裹盒)進行 'inline-table' 的基線垂直對齊。表格包裹盒的寬度是裡面表格盒邊框邊的寬度(在 17.5.2 小節描述)。表格上 'width' 和 'height' 的百分比值相對於表格包裹盒的包含塊,而不是表格包裹盒本身。
使用者代理會把表格元素上 'position'、'float'、'margin-*'、'top'、'right'、'bottom'、'left' 屬性的計算值用在表格包裹盒而不是表格盒上 ― 其他不繼承的屬性用在表格盒而不是表格包裹盒上。(表格盒與表格包裹盒沒從表格元素得到屬性值的屬性改使用初始值。)
取值: | top | bottom | inherit |
初始: | top |
適用於: | 'table-caption' 元素 |
繼承: | 是 |
百分比: | (不適用) |
媒介: | 視覺 |
計算值: | 同指定值 |
本屬性可以用來指定表格說明盒相對於表格盒的位置。本屬性各取值的意義如下:
top
down
網頁作者可以用 'text-align' 屬性來進行表格說明內容的水平對齊。
caption { caption-side: bottom; width: auto; text-align: left }
内部表格元素生成一个由内容和边框组成的矩形盒子。单元格也有内边距。内部表盒元素没有外边距。
这些盒子的可视化布局基于一个矩形、不规则的行和列组成的网格。这些盒子根据下列规则占据一系列网格单元。这些规则不适用于HTML 4或更早版本;HTML增加了其跨越行和列的限制。
在边框折叠模型下的行、列、行群组和列群组的边缘与单元格的边框中间的假定网格线一致。(因此,在该模型下,所有的行一起没有空隙地完全覆盖表格;列亦如此。)在边框分离模型下,这些边缘与单元格的边框边缘一致。(因此,在该模型下,与‘border-spacing’属性一致,在行、列、行群组或列群组之间存在空隙。)
下面的例子解释规则5。下列非法的(X)HTML片段定义了冲突的单元格:
1 | 2 | 3 | 4 |
5 |
为了确定每个表格单元格的背景,不同的表格元素可能会被认为是六个叠加层。能被看到的表格的背景只能是其上所有层均为透明背景的一个层上设置的背景。
“缺失的单元格”是指那些在行/列网格中没有被元素或伪元素占据的单元格。在显示缺失的单元格时,就好像一个匿名表格单元格盒子占据了网格中它的位置。
在下面的例子中,第一行包含了四个非空单元格,但第二行仅包含了一个非空单元格。因此,在第二行中,除了该非空单元格和从第一行中穿越过来的单元格外,表格的背景穿透过来。下面的HTML代码和样式规则Table example
1 | 2 | 3 | 4 |
5 |
需要注意的是,如果表格设置了“border-collapse: separate”,‘border-spacing’属性所给出的区域的背景总是表格元素的背景。参见边框分离模型。
CSS没有定义表格的“最佳”布局,因为在大多数情况下,所谓最佳因人而异。CSS定义了在布局表格时需要遵守的约束。用户代理可能会使用其希望的任何算法,并且自由的选择牺牲精确度而提高渲染速度,但这不适用于选择“固定布局算法”时。
值得注意的是本节重写了10.3章中描述的适用于计算宽度的规则。尤其是,如果表格的外边距被设为“0”且宽度被设为“auto”时,表格不会自动填充包含块。然而,一旦确定了表格‘width’的计算值(使用下面给出的算法,或者,如果恰当,使用其他的由用户代理确定的算法)就会应用10.3章的其他部分。因此,表格可以使用左右‘auto’外边框产生居中效果。
未来对CSS的更新可能会介绍使表格自动适应其包含块的方法。
'table-layout'(表格布局)
取值: | auto(自动)| fixed(固定) | inherit |
初始: | auto |
適用於: | ‘table’和‘inline-table’元素 |
繼承: | 否 |
百分比: | (不適用) |
媒介: | 视觉 |
計算值: | 同指定值 |
‘table-layout’属性控制用于布局表格单元格、行和列的算法。它的值拥有如下意义:
fixed
auto
这两个算法在下面描述。
使用此(快速)算法,表格的水平布局不受单元格内容的影响;其只受表格宽度、列宽度和边框或单元格间距的影响。
表格宽度可能会使用‘width’属性精确的指定。值‘auto’(同时适用于‘display: table’和‘display: inline-table’)意味着使用自动表格布局算法。然后,如果表格是一个默认流中的块级表格(‘display: table’),即使其宽度被指定为‘auto’,用户代理亦可能会(但不是必须)使用10.3.3节中的算法来计算宽度并应用固定表格布局。
table { table-layout: fixed; margin-left: 2em; margin-right: 2em }
在固定表格布局中,按照下面的描述确定每一列的宽度:
表格的宽度是表格元素‘table’属性的值和列宽度总和(加上单元格边距或边框)中的较大值。如果表格宽于列,则额外的空间将分布于各列。
如果随后各行中的列数大于表格列元素确定的数目和第一行确定的数目中的较大值,则额外的列可能不会显示。CSS 2.1没有定义需要显示它们时如何计算列和表的宽度。在使用‘table-layout: fixed’时,编码人员不应在第一行中遗漏任意一列。
在这种机制下,用户代理可以在完整的接收到第一行时就开始布局该表格。随后各行中的单元格不会影响列的宽度。内容溢出的单元格由‘overflow’属性确定如何剪裁这些溢出的内容。
在此算法中(一般要求不超过两次传递),表格的宽度有列的宽度给出(包含边框)。在撰写本规范时,此算法反映了几种常见HTML用户代理的行为。用户代理必须要实现本算法来确定‘table-layout’为‘auto’时的表格布局;它们可以使用任意其他算法,即使它们会产生不同的行为。
对自动表格布局的输入必须仅包含包含块的宽度和表格及其任意后裔的内容(及其上的CSS属性)。
本节的剩余部分是不规范的。
由于此算法需要用户代理在确定最终布局之前访问全部内容,可能会需要多次传递,因此其效率可能非常低下。
按照下面的描述确定每一列的宽度:
这给出了每一列的最大、最小的宽度。
标题宽度最小值(CAPMIN)可以通过将每个标题的最小标题外宽度计算为包含格式化为“display: block”的标题的假定表格单元格的最小内容宽度来确定。最大的最小标题外宽度就是标题宽度最小值。
列和标题宽度按照下面的描述影响最终表格宽度:
列宽度的百分比值与表格宽度相关联。如果表格设置了‘width: auto’,则百分比值表示一个在列宽度上的约束条件,用户代理应当试图满足该约束。(显然,这不总是可行:如果列的宽度为“110%”,则该约束不可能满足。)
表格的高度由‘table’或‘inline-table’元素的‘height’属性给出。其值‘auto’表示其高度是行高度加上任意单元格间距或边框的总和。它的任意的值被视为最小值。CSS 2.1没有定义‘height’属性造成表格高于其不应用该属性时的高度所产生的额外控件将如何分布。
‘table-row’元素的盒子的高度在用户代理确认该行之内的所有单元格均可用后立刻计算:其是行的计算后‘height’、行内各单元格的计算后‘height’以及单元格所需要的最小高度(MIN)之中的最大值。‘table-row’的‘height’属性的值‘auto’表示用于布局的行高是MIN。MIN取决于单元格盒子的高度和单元格盒子的对齐方式(与对行盒子高度的计算类似)。CSS 2.1没有定义在表格单元格和表格行被指定为百分比值时如何计算其高度。CSS 2.1没有定义行群组上‘height’的意义。
在CSS 2.1中,单元格盒子的高度是其内容所需的最小高度。表格单元格的‘height’属性可以行的高度(见上面),但不会影响单元格盒子的高度。
CSS 2.1没有指定指定跨越多行的单元格对行高计算的影响,但涉及的行的总高度必须足够高,以便其能够包含单元格跨域这些行。
每个表格单元格的‘vertical-align’属性确定其在行内的对齐方式。每个单元格的内容都和行本身一样,拥有基线、顶部、中部和底部。在表格上下文中,‘vertical-align’的值拥有下列意义:
baseline(基线)
top(顶部)
bottom(底部)
middle(中部)
sub、super、text-top、text-bottom、
单元格的基线是该单元格内第一个内部流的行盒或表格行中首先出现的一个的基线。如果没有这样的行盒或表格行,则基线为单元格盒子的内容边缘的底部。为了确定基线,拥有滚动机制(参见‘overflow’属性)的内部流盒子必须被认为其已经滚动至源位置。值得注意的是单元格的基线可能会低于其底部边框,详见下面的例子。
从单元格盒子的顶部到各个拥有‘vertical-align: baseline’的单元格的基线的最大距离被用来设置该行的基线。下面是一个例子:
单元格盒子1、2与其基线对齐。单元格盒子2拥有基线的最大高度,所以其确定了行的基线。
如果一行没有与基线对齐的单元格,则该行的基线是行内最低的单元格的底部内容边缘。
为了避免模棱两可的情况,单元格的对齐方式按照下列顺序确定:
小于该行高度的单元格盒子,将会获得额外的顶部或底部内边距。
div { height: 0; overflow: hidden; }
单元格盒子中行级内容的水平算法可以通过在单元格上的‘text-align’属性的值来确定。
‘visibility’属性在行、行群组、列和列群组元素上拥有值‘collapse’。该值会造成行或列从显示中移除,且该空白通常由其他内容可用的行或列取代。跨越与折叠的列或行相交叉的行或列的内容将被剪裁。然后,隐藏的行或列不会在其他方面影响表格的布局。这允许动态的移除表格的行或列,而不用为了列约束中的潜在变化而强制重新布局该表格。
在CSS中存在两种不同的设置表格单元格边框的模型。一种更加适合在单独单元格周围的所谓分离边框,另一种适合从表格一端到另一端的连续的边框。许多边框样式同时适用于两种模型,所以在确定使用何种模型时因人而异。
‘border-collapse’
取值: | collapse(合并) | separate(分离) | inherit |
初始: | separate |
適用於: | ‘table’及‘table-caption’元素 |
繼承: | 是 |
百分比: | (不適用) |
媒介: | 视觉 |
計算值: | 同指定值 |
该属性选择表格的边框模型。值‘separated’选择边框分离模型。值‘collapse’选择边框合并模型。这些模型将在下面描述。
‘border-spacing’
取值: | <长度> <长度>? | inherit |
初始: | 0 |
適用於: | ‘table’及‘table-caption’元素* |
繼承: | 是 |
百分比: | (不適用) |
媒介: | 视觉 |
計算值: | 两个绝对长度 |
长度指定了邻近单元格边框间的距离。如果指定了一个长度,则它同时给出了水平和垂直间距。如果指定了两个长度,则第一个长度给出了水平间距、第二个长度给出了垂直间距。长度不能为负值。
从表格边框到处于表格边缘的单元格的边框直接的距离是对应一侧的表格的内边距加上相应的边框间距。例如,在右侧,其距离为右内边距(padding-right)+水平边框间距(border-spacing)。
表格的宽度是从左侧内边距边缘内侧到右侧内边距边缘内侧直接的距离(包含边框间距但不包含内边距和边框)。
但是,在HTML和XHTML1中,元素的宽度是从左侧边框边缘到右侧边框边缘直接的距离。在此模型下,每个单元格都拥有一个独立的边框。‘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 */
‘empty-cells’
取值: | show(显示) | hide(隐藏) | inherit |
初始: | show |
適用於: | ‘table-cell’元素 |
繼承: | 是 |
百分比: | (不適用) |
媒介: | 视觉 |
計算值: | 同指定值 |
在边框分离模型中,该属性控制环绕在没有可视化内容的单元格周围的边框和背景的显示效果。空单元格以及‘visibility’属性被设为‘hidden’的单元格被认为没有可视化内容。除非单元格包含至少一个下列内容,则其为空:
若概述的值为‘show’,则边框和背景将被绘制在空单元格周围/之后(与普通单元格一样)。
值‘hide’意味着边框和背景将不会被绘制在空单元格周围/之后(参见17.5.1节的第6点)。此外,如果行内的所有单元格的值都是‘hide’且都没有可视化内容,则该行的高度为零,并且该行的垂直边框间距仅在一侧出现。
table { empty-cells: show }
在边框合并模型中,可以指定边框将会环绕单元格、行、行群组、列和列群组的全部或部分。HTML的的边框的“rules”属性可以指定它。
边框居中在单元格直接的网格线上。用户代理必须找到一个一致性规则来在奇数离散单元的情况向四舍五入。
下面的图表展示了表格宽度、边框宽度、内边距和单元格宽度之间的关系。它们的关系有下面的等式给出,它适用于表格的每一行:
“n”是行内单元格的数目;“左内边距i”和“右内边距i”指的是第i个单元格的左、右内边距;“边框宽度i”指的是在第i个单元格和第i+1个单元格直接的边框。
用户代理必须通过检查表格第一行中的第一个和最后一个单元格来计算表格的初始左、右边框宽度。表格的左边框宽度是第一个单元格折叠后的左边框的一半;表格的右边框是最后一个单元格折叠后右边框的一半。如果随后各行中的折叠后左、右边框较大,则额外宽度将移除的表格的外边距区域。
表格的顶部边框宽度可以通过检查所有与表格的顶部边框折叠的单元格来计算。表格的顶部边框宽度等于折叠后顶部边框最大值的一半。表格的底部边框宽度可以通过检查所有与表格的底部边框折叠的单元格来计算。表格的底部边框等于折叠后底部边框最大值的一半。
在确定表格是否会溢出其祖先时,需要考虑泄露到外边距的边框(参见‘overflow’)。
需要注意的是,在此模型下,表格的宽度包括表格边框的一半。同样,在此模型下,表格没有内边距(但拥有外边距)。
CSS 2.1没有定义表格元素背景的边缘位置。
在边框合并模型中,每个单元格的每个边缘处的边框都可能会由在边缘处接触的不同元素上的边框属性设置(单元格、行、行群组、列、列群组和表格本身),并且这些边框可能会在宽度、样式和颜色上改变。处理这些问题的经验是在每个边缘处选择最“显眼”的边框样式,但如何其样式中出现了‘hidden’则无条件的消去边框。
下列规则可以确定在冲突的时候会选择哪种边框样式:
table { border-collapse: collapse; border: 5px solid yellow; }*#col1 { border: 3px solid black; }td { border: 1px solid red; padding: 1em; }td.cell5 { border: 5px dashed blue; }td.cell6 { border: 5px solid green; }
HTML源如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
其结果如下:
‘border-style’属性的某些值在表格中拥有和其他元素不同的意义。在下面的列表中,这些值将以型号标出。
none
*hidden
dotted
dashed
solid
double
groove
ridge
*inset
*outset