(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!)
(注2:更多内容请查看我的目录。)
本文定义了CSS中表格的处理模型。这种处理模式的一部分就是布局。对于布局,本文介绍两种算法; 第一种是固定表格布局算法,其定义很明确,但第二种是自动表格布局算法,该规范没有完全定义。
对于自动表格布局算法,一些广泛部署的实现已经实现了相对紧密的互操作性。
表格布局可以用来表示数据之间的表格关系。开发者以文档语言指定这些关系,并可以使用CSS 2.2指定他们的表示。
在可视化媒体中,CSS表格也可以用来实现特定的布局。在这种情况下,开发者不应该在文档语言中使用与表格相关的元素,而应该将CSS应用于相关的结构元素以实现所需的布局。
开发者可以将表格的视觉格式指定为矩形网格单元格。单元格的行和列可以组织成行组和列组。行,列,行组,列组和单元格可以在它们周围绘制边框(CSS 2.2中有两个边框模型)。开发者可以在单元格中垂直或水平对齐数据,并可以将一行或者一列的所有单元格数据对齐。
如下,是一个简单的三行,三列的HTML 4中描述的表格:
<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: 3px solid blue }
tr#row2 { border: 1px solid black }
tr#row3 { border: 1px solid black }
但请注意,行周围的边框于行相交处重叠。row1和row2之间的边界是什么颜色(黑色或蓝色)和厚度(1px或3px)?我们在关于边界冲突解决的部分讨论这一点 。
以下规则将表头放在表格的上方:
caption { caption-side: top }
上例显示了CSS如何作用于 HTML 4元素; 在HTML 4中,各种表格元素(TABLE,CAPTION,THEAD,TBODY,TFOOT,COL,COLGROUP,TH和TD)的语义是明确定义的。在其他文档语言(如XML应用程序)中,可能没有预定义的表格元素。因此,CSS 2.2允许开发者通过“display”属性将文档语言元素“映射”到表格元素。例如,以下规则使FOO元素行为表现和HTML TABLE元素一样,BAR元素像CAPTION元素一样:
FOO {display:table}
BAR {display:table-caption}
我们在接下来讨论各种表格元素。在本文中,术语表元素table element是指任何涉及创建表的元素。内部表元素internal-table-element是生成行row、行组row group、列column、列组column group或单元格cell的元素。
CSS表格模型基于HTML4表格模型,其表格结构与表格的可视布局紧密相关。在此模型中,表格由可选标题caption和任意数量行的单元格组成。作者在文档语言中明确表格模型被为“行主要”。一旦指定了所有行,就会派生出列(每行的第一个单元格属于第一列,第二个单元格属于第二列,......)。行和列可以在结构上分组,并且该分组会通过表现反映出来(例如,可能会围绕行来绘制border)。
因此,表格模型由表格tables,标题captions,行 rows,行组row groups(包括标题组header groups和页脚组footer groups),列columns,列组column groups和单元cells组成。
CSS模型不要求文档语言包含对应这些组件的每一个元素。对于没有预定义表元素的文档语言(如XML应用程序),作者必须将文档语言元素映射到表元素,这是通过“display”属性完成的。下面的“display”值将表格格式化规则分配给任意元素:
具有这些display值的替换元素在布局过程中被视为其给定的display类型。例如,设置为'display:table-cell'的图像将填充可用的单元格空间,其尺寸可能会影响表格大小算法,如同普通单元格一样。
将display设置为'table-column'或'table-column-group'的元素不会被渲染(就像它们有'display:none'一样),但是它们是有用的,因为它们可能具有某些属性为其所代表的列包含特定的样式。
附录中 default style sheet for 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以外的文档语言可能不包含CSS 2.21表模型中的所有元素。在这些情况下,必须假定“缺失”元素才能使表格模型起作用。任何table元素都会自动生成必要的匿名表对象,由至少三个对应于'table'/'inline-table'元素,'table-row'元素和'table-cell'元素的嵌套对象组成。缺失元素根据以下规则生成匿名对象(例如,可视化表格布局中的匿名盒):
我们为这些规则定义如下术语:
出于这些规则的目的,脱离标准流元素被视为零宽度零高度的行内元素。它们的包含块也会被对应此选择。
以下步骤分三个阶段进行:
表格单元格可能属于两个上下文:行和列。但是,在源文档中,单元格是行的后代,而不是列。尽管如此,通过在列上设置属性可以影响单元格的某些方面。
以下属性适用于column和column-group元素:
以下是在列上设置属性的样式规则的一些示例。前两条规则一起执行HTML 4的“rules”属性,其值为“cols”。第三条规则使“totals”列变为蓝色,最后两条规则通过使用固定布局算法fixed layout algorithm显示如何使列成为固定大小。
col { border-style: none solid }
table { border-style: hidden }
col.totals { background: blue }
table { table-layout: fixed }
col.totals { width: 5em }
就VFM而言,table可以表现为 block-level(用于'display:table')或 inline-level(用于'display:inline-table')元素。
在这两种情况下,该表都会生成一个称为表格包装盒table wrapper box的主要块容器盒principal block container box ,其中包含table box本身和任何caption boxes(按文档顺序)。该table box是包含表的内部表盒internal table boxes的一个块级盒。caption boxes是主要的块级盒,它们保留自己的content, padding, margin, and border 区域,并在表格包装盒内呈现为普通块盒。caption boxes放置在table box之前还是之后由'caption-side'属性决定,后面会讲到。
table wrapper box对于'display:table'是块级的,对于 'display:inline-table'是行内级的。table wrapper box建立一个BFC,而table box建立一个表格格式上下文table formatting context.。table box (不是table wrapper box)用于为“inline-table”执行基线垂直对齐。table wrapper box的宽度是其内部table box 的border-edge width,如第17.5.2节所述。作用于table的“width”和“height”的百分比值是相对于table wrapper box的 containing block,而不是table wrapper box本身。
table element的属性 'position', 'float', 'margin-*', 'top', 'right', 'bottom', 和 'left'的计算值作用于table wrapper box而不是table box; 所有其他非可继承属性的值作用于 table box而不是table wrapper box。(当table box和table wrapper box中未使用table element的值时,将使用初始值initial values替代。)
上面有标题的表格图Diagram of a table with a caption above it
caption-side
此属性指定caption box相对于table box的位置。其值具有以下含义:
注:CSS2描述了不同的宽度和水平对齐行为。该行为将在CSS3中使用此属性的值“top-outside”和“bottom-outside”引入。
如果要在caption box内水平对齐标题内容,请使用'text-align'属性。
在此示例中,“caption-side”属性将标题放置在表格下方。标题将与表格的父项一样宽,并且标题文本将左对齐。
caption {
caption-side: bottom;
width: auto;
text-align: left
}
Internal table elements生成的矩形盒box,会参与由table box创建的表格格式上下文TFC。这些框有content和borders,cells也有padding。Internal table elements没有margins。
这些框的视觉布局是由一个矩形的、不规则的行和列网格控制的。每个盒子占据了整个网格单元的数量,根据下面的规则来确定。这些规则不适用于HTML 4或早期的HTML版本;HTML对行和列跨度有自己的限制。
<table>
<tr>
<td>1 </td>
<td rowspan="2">2 </td>
<td>3 </td><td>4 </td>
</tr>
<tr>
<td colspan="2">5 </td>
</tr>
</table>
用户代理可以在视觉上重叠单元格,如左图所示,或者移动单元格以避免视觉重叠,如右图所示:
错误表格的两种可能渲染方式Two possible renderings of an erroneous HTML table
为了找到每个表格单元格的背景,不同的表格元素可以被认为是在六个叠加层上。在其中一个图层中的元素上设置的背景只有在它上面的图层具有透明背景时才可见。
表层架构Schema of table layers
"missing cell"是行/列网格row/column grid中未被元素或伪元素占据的单元格。Missing cells的单元格就像被一个anonymous table-cell box占据了它们在网格中的位置一样被渲染。
在下面的示例中,第一行包含四个非空单元格non-empty cells,但第二行仅包含一个非空单元格,因此表格背景会被穿透展示,除非第一行的单元格跨越此行。以下是HTML代码和样式规则:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
<HEAD>
<TITLE>Table example</TITLE>
<STYLE type="text/css">
TABLE { background: #ff0; border: solid black;
empty-cells: hide }
TR.top { background: red }
TD { border: solid black }
</STYLE>
</HEAD>
<BODY>
<TABLE>
<TR CLASS="top">
<TD> 1
<TD rowspan="2"> 2
<TD> 3
<TD> 4
<TR>
<TD> 5
<TD>
</TABLE>
</BODY>
</HTML>
可能会被格式化如下:
表格底部有空单元格Table with empty cells in the bottom row
请注意,如果表具有'border-collapse:separate'属性,则由'border-spacing'属性给出的区域的背景总是表格元素的背景。详见分离的边框模型。
CSS并没有为表格定义一个“最佳”布局,因为在许多情况下,”最佳“就是一个品味问题。CSS确定了用户代理在表格布局时必须遵守的约束。用户代理可以使用他们想做的任何算法,并且可以自由地选择渲染速度而不是精度,除非选择了“固定布局算法fixed layout algorithm”。
请注意,本节将重写如第10.3节section 10.3
所述的适用于计算宽度的规则。特别是,如果一个表的边距margins设置为“0”和“auto”的宽度,则表格不会自动调整大小以填充其包含的块。然而,一旦找到了表的“width”的计算值(使用下面给出的算法,或者在适当情况下,使用其他一些UA依赖算法),那么第10.3节部分的其他部分就应用了。因此,一个表可以使用左右两个'auto' margins实现居中。
CSS的未来更新可能会引入使表格自动适应其包含块的方法。
table-layout
‘table-layout’属性用于控制应用于表的cells, rows,和columns的布局算法。其值具有如下含义:
使用这种(快速)算法,表的水平布局不依赖于单元格内容; 它仅取决于表格的宽度,列的宽度以及borders或者单元格间距cell spacing。
表格的宽度可以用'width'属性明确指定。如果该属性值为'auto'(对于'display:table'和'display:inline-table')意味着使用自动表格布局算法。但是,如果该表是标准流中的块级表('display:table'),则UA可以(但不是必须)使用10.3.3的算法计算宽度并应用固定表格布局,即使指定的width是'auto'。
如果UA在'width'为'auto'时支持固定表格布局,则以下内容将创建一个比其包含块窄4em的表格:
table {
table-layout: fixed;
margin-left: 2em;
margin-right: 2em
}
在固定表格布局算法中,每列的宽度确定如下:
表格的宽度是表格元素的'width'属性的值和所有列宽的总和(加上单元格间距或边框)中较大的那个 。如果表格比列宽,额外的空间应该分布在列上。
如果后续行的列数多于由表列元素table-column elements和第一行确定的数字中的较大值,多余的列不会被渲染。如果它们被渲染,CSS 2.2没有定义列和表的宽度。当使用'table-layout:fixed'时,开发者不应该忽略第一行的列。
以这种方式,一旦接收到完整的第一行,用户代理就可以开始进行表格布局。后续行中的单元格不会影响列宽。任何具有溢出内容的单元使用“overflow”属性来确定是否裁剪溢出内容。
***** 5.2.2 自动表格布局 Automatic table layout
在这个算法(通常不会超过两遍)中,表的宽度是由其列的宽度(以及插入边界intervening borders)给出的。该算法反映了在编写该规范时几种流行的HTML用户代理的行为。在'table-layout'为'auto' 的情况下,UA不需要实现该算法来确定表格布局; 他们可以使用任何其他算法,即使会导致不同的行为。
对自动表格布局的输入只能包含包含块的宽度 以及 表格及其任何后代的内容和其上设置的任何CSS属性。
本节其余内容是非规范性的。该算法可能导致效率低下。在此算法中,行(和行组)和列(和列组)都约束并受其包含的单元的维度约束。设置列的宽度可能会间接影响行的高度,反之亦然。在此不予详述。可以参考Column widths。
表格高度由'table'或'inline-table'元素的'height'属性给出。'auto'值表示高度是行高度row heights加上任何单元格间距cell spacing或边界borders的总和。任何其他值都被视为最小高度。当“height”属性导致表格变高时,CSS 2.2没有定义多余的空间如何分布。
一旦用户代理具有行中的所有单元格,就计算'table-row'元素框的高度:它是行计算的'height'的最大值,行中每个单元格计算的'height'和单元格所需的最小高度(MIN)。“表格行” 的height值为“auto”表示用于布局的行高度是MIN。MIN取决于单元格高度和单元格对齐方式(很像计算行盒line box高度)。CSS 2.2没有定义表单元格和表行的高度是如何用百分比值指定其高度的。CSS 2.2没有定义行组上“高度”的含义。
在CSS 2.2中,单元格盒的高度是内容所需的最小高度。表格单元格的height属性可以影响行的高度(请参见上文),但不会增加单元格盒的高度。
CSS 2.2没有指定跨越多行的单元格如何影响行高计算,但所涉及行高的总和必须足够大以涵盖跨行的单元格。
每个表格单元格的'vertical-align'属性决定了它在行内的对齐方式。每个单元格的内容都有一个基线baseline,一个顶部top,一个中间middle和一个底部bottom,行本身也是如此。在表格的上下文中,'vertical-align'的值具有以下含义:
单元格的基线是单元格中第一行标准流内行盒line box的基线,或单元格中第一个标准流内表行table-row的基线,以第一个为准。如果没有这样的行框或表行,则基线是单元格盒的内容边缘content edge的底部。为了查找基线,必须将具有滚动机制的标准流内盒子(请参阅'overflow'属性)视为滚动到其原始位置。注意,单元格的基线可能会低于其底部边界,请参见下面的示例。
所有单元格中“vertical-align”的单元格顶部与基线之间的最大距离用于设置该行的基线。这里有个例子:
显示表格单元格中'vertical-align'各种值的影响的图表Diagram showing the effect of various values of 'vertical-align' on table cells
单元格盒cell box1和2在其基线上对齐。单元格盒2具有基线以上的最大高度,因此可以确定该行的基线。
如果某行没有与其基线对齐的单元格盒,则该行的基线是该行中最低单元格的底部内容边缘。
为了避免模棱两可的情况,单元格的排列按以下顺序进行:
小于该行高度的单元格盒会收到额外的顶部或底部padding。
此示例中的单元格的底部边界下方有一个基线:
div { height: 0; overflow: hidden; }
<table>
<tr>
<td>
<div> Test </div>
</td>
</tr>
</table>
单元格盒中inline-level content的水平对齐可以通过单元格上的'text-align'属性值来指定。
row, row group, column和 column group元素的“visibility”属性值可以取为'collapse'。该值导致整个行或列从显示中移除,并且由行或列正常占据的空间将用于其他内容。与折叠的列或行相交的跨行和列的内容会被剪切。但是,对行或列的抑制不会影响表格的布局。这允许动态效果删除表格行或列而不强制对表格进行重新布局,以考虑列约束中的潜在变化。
为CSS中的表单元格设置边界有两种不同的模式。其中一个适用于在单个单元格盒周围的所谓分离边框separated borders,另一个适合于从表的一端到另一端的连续边界。这两种模式都可以实现许多边界样式,所以决定使用哪一种通常只是开发者的品味而已。
border-collapse
该属性选择表格的边框模型。值'separate'选择分离边框边框模型separated borders border model。值'collapse'选择折叠边框模型collapsing borders model。这些模型如下所述。
border-spacing
注意:用户代理也可以将'border-spacing'属性应用于'frameset'元素。本规范并未定义哪些元素是'frameset'元素,这取决于文档语言。例如,HTML4定义了一个<FRAMESET>元素,而XHTML 1.0定义了一个<frameset>元素。'frameset'元素上的'border-spacing'属性可以被用作非标准'framespacing'属性的有效替代。
lengths指定分隔相邻单元格边界的距离。如果指定了一个length,则会同时提供水平和垂直间距。如果指定了两个,则第一个给出水平间距,第二个给出垂直间距。length不一定是负值。
表边框和单元格边缘之间的距离是表的内边距padding ,加上相应的边框间距border spacing distance。例如,在右侧,距离是padding-right + horizontal border-spacing。
表格边框与表格边框之间的距离是该表格的边框填充以及相关的边框间距。例如,在右侧,距离是填充右边 + 水平边框间距。
表的宽度是从left inner padding edge到right inner padding edge的距离(包括border spacing,但不包括padding 和 border)。
但是,在HTML和XHTML1中,<table>元素的宽度是从left border edge 到right border edge 的距离。
注:在CSS3中,这个特殊的需求将根据UA样式表规则和'box-sizing'属性来定义。
在这个模型中,每个单元都有一个单独的边界。在“border-spacing”属性指定相邻单元格的border之间的距离。在此空间中,row, column, row group, 和 column group的背景不可见,允许表格背景显示。row, column, row group, 和 column group不能有borders(即用户代理必须忽略这些元素的边框属性)。
下图中的表格可能是这样的样式表的结果:
table { border: outset 10pt;
border-collapse: separate;
border-spacing: 15pt }
td { border: inset 5pt }
td.special { border: inset 10pt } /* The top-left cell */
图片上传失败...(image-c9df60-1520163880252) set to a length value. Note that each cell has its own border, and the table has a separate border as well.
empty-cells
在separated borders model中,此属性控制在没有可见内容的单元格周围绘制边框和背景。“visibility”属性设置为“hidden”的空单元格和单元格被视为没有可见内容。单元格为空,除非它们包含以下一项或多项:
table { empty-cells: show }
在 collapsing border model中,可以指定围绕全部或部分单元格,行,行组,列和列组的边框。HTML的“rules”属性的边界可以用这种方式指定。
边框以单元格之间的网格线为中心。在奇数个离散单位(屏幕像素,打印机点)的情况下,用户代理必须找到一致的舍入规则。
下表显示了表格的宽度,边框的宽度,填充和单元格宽度如何相互作用。它们的关系由以下等式给出,该等式适用于表的每一行:
这里n是行中单元的数量, padding-lefti 和 padding-righti 分别指的是单元格的左右padding,和 border-widthi 指单元格i和i+1之间的border。
UA必须通过检查表格第一行中的第一个和最后一个单元格来计算表格的初始左边界和右边界宽度。表格的左边框宽度是第一个单元格的折叠左边框的一半,并且该表格的右边框宽度是最后一个单元格的折叠右边框的一半。如果后面的行具有较大的折叠左右边界,则任何多余部分溢出到表格的margin area。
表格的顶部边框宽度是通过检查所有用表格顶部边框折叠顶部边框的单元格来计算的。表格的顶部边框宽度等于最大折叠顶部边框的一半。通过检查底部边界与表底部折叠的所有单元格计算底部边框宽度。底部边框宽度等于最大折叠底部边框的一半。
当确定表是否溢出某个祖先时,会考虑溢出到margin中的任何border(参见'overflow')。
Schema showing the widths of cells and borders and the padding of cells.
请注意,在此模型中,表格的宽度包括表格border的一半。而且,在这个模型中,一个表格没有padding(但有margin)。
CSS 2.2没有定义表格元素背景边缘的位置。
在collapsing border model中,每个单元格的每个边缘处的边框可以由在该边缘处相遇的各种元素(单元格,行,行组,列,列组和表格本身)上的边界属性指定,并且这些边框的宽度,样式和颜色可能会有所不同。经验法则是,在每个边缘选择最“醒目”的边框样式,除非任何出现的“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; }
<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="cell5"> 5
<TD class="cell6"> 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
这是一个隐藏的折叠边框的例子:
<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>
Table with two omitted internal borders
“border-style”的某些值在表中的含义不同于其他元素。在下面的列表中,他们用星号标出。