此文根据Chris Coyier的《A Complete Guide to the Table Element》所译,整个译文带有我自己的理解与思想,如果译得不好或不对之处还请同行朋友指点。
一个非常基础的例子
下面是一个非常简单的表格数据例子:
这是一个跨多轴的数据。想象下,通过你得手指划过某一行来了解某个人的相关信息。或者从上至下来感受某个数据点的模式和变化。
表头和表体
上面这个基础例子中我们没有做的一件事是没有语义地指出第一行是该表格的头部。我们本应该这么做。整个第一行的部分没有包含数据,它只是每个列的标题。因此,我们可以<thead>
元素来完成这件事情,它会包裹第一个<tr>
元素(它会包裹所有的行所需要的头部信息)
HTML代码如下所示:
当你使用了<thead>
元素后,<table>
元素中不能有直接的<tr>
子元素,所有的行必须存在于<thead>
,<tbody>
和<tfoot>
里面。要注意的是我们会把所有的数据行包含在<tbody>
里面。
表尾
连同<thead>
和<tbody>
一起的还有<tfoot>
,用于包裹指出表格页脚的行。和<thead>
一样,它只是语义地指出了辅助信息,没包含别的数据。
<tfoot>
独一无二的一点是它在HTML中的位置,它紧跟着<thead>
并位于<tbody>
的前面!你可能会认为它是table
标签结束前的最后一个元素,但情况并不是这样。因为页脚可能包含了用于理解表格的必要信息,因为在资源序列中它应当排在在数据的前面。
尽管首先在资源序列中出现,<tfoot>
确实渲染在了表格的底部,这使其成为一个不同寻常的HTML元素。
举个例子,它可以用于这样的场景,在一个很长或很高的表格中,<tfoot>
重复了表头的信息,使得读者更容易地在底部看到列表的标题信息,而不用回到头部查看。但你并没有必要这样来使用它。
在一些元素位置根据需要从上至下跳动的布局中,<tfoot>
是个不错的技巧。举个例子,虽然一个导航在屏幕的底部,但在HTML源码中导航应该在顶部。
单元格:td和th
在表格中一个独立的单元格总是<td>
或<th>
两者之一,只要你愿意,你可以把任何东西放进表格的单元格中,但要使这些元素成为表格中的单元格元素。<th>
是“表格的标题”,<td>
是“表格的数据”。
使用我们现有的简单例子,顶行是所有的头部信息。它们是数据的标题而不是数据,而剩下的所有行都为数据。如下:
<th>
元素并不是必须放在<thead>
元素当中。它们简单地指出了头部信息。因此它们也能用于<tbody>
元素的第一行当中。我们会在后面给出这样的一个例子。
基本样式
你看到的大多数表格都用颜色和线条来区别表格的不同部分。边框是非常常见的。默认的,所有的单元格相互之间都有2px的空隙(通过用户代理样式表给出)
注意第一行和余下部分轻微的额外差距。这是默认的应用在和中的 border-spacing 导致他们产生了一点间隔。这不是外边距,他们没有折叠。你可以像这样来控制间隔:
table { border-spacing: 0.5rem; }
但更常见的做法是移除这些间隔,这个属性能够完全忽略和折叠这些间隔,像如下设置:
table { border-collapse: collapse; }
小小的内边距,边框并使<th>
元素左对齐就能样式化一个简单的表格:
合并单元格
有两个能应用在任何单元格中的重要的属性(<td>
或<th>
):colspan 和 rowspan 。他们接受任何大于等于2的正整数。如果一个 td 元素的 colspan 值为2(<td colspan="2">
),它将仍然是单独的单元格,但它会在一行中水平的占据两个单元格的空间。rowspan 也一样,但它作用于垂直方向。
在你开始准备使用合并单元格的工作前你必须先进行一点心算。合并列相对比较简单。所有的单元格在其数量值上等价于1,如果它具有 colspan 属性,则等价于更多。合计一行中的每个单元格的值则可以得到表格行的最终值。其他的每一行的值都必须精确地等于该值,否则你将得到一个非矩形的尴尬的表格布局。(最长的表格行将会突出)
合并行是相似的,只是它难度要稍大一点并需要思维跳跃。因为列并不像行那样分组。如果一个表格元素具有 rowspan 属性,它会垂直跨越两行。这意味着它代表的单元格数得到了+1。
在你得脑袋中想象出它们可能有点难度,但我们是开发者,相信我们能做到这点。=)
实际上这些属性经常仅仅是简单地被应用,例如合并几个相关联的表头:
宽度自适应... 或包含在容器中... 或撑破容器
表格元素在其自身应该占据多宽的问题上是不同寻常的,它表现地像一个块级元素(如:<div>
),如果你把一个表格放在另一个表格后面,每一个都会分解到它自己的行当中。但表格的实际宽度却仅按照它所需要的给出。
如果在表格最宽的行中文本的宽度为100px宽,则这个表格宽度为100px。如果文本的数量宽度比表格的外容器要宽,则文本将会被包裹(通过折行)起来。
然而如果文本被设置为非包裹(例如: white-space: nowrap;),表格可能会撑破容器。因为单元格也是非包裹的,所以如果内容太多,表格则会撑破容器。
两轴表格
有时候表格具有两个轴是有意义的。像一个交叉引用的情况。下面以一个乘法表为例子:
在这种情况我可能会省略 <thead>
标签即使第一行全是表格头部信息。因为这个头部并不显得十分重要,将它单独分行放在<thead>
中会让人感到有点奇怪。因此只要让第一行的所有列都使用<th>
标签并让余下的行的第一列使用<th>
标签就可以了。
什么时候使用表格
现在让我们缓一缓并讨论一下应该何时使用表格,或许你已经听过这类型的建议:表格是为列表式的数据准备的(请看本文的第一个句子)。
把什么东西放在表格当中是比较合适的?这里列出了一些:一个计划表/价格表/特性比价,保龄球分数,网格式的员工信息,财务数据,日历,营养成分表信息版,逻辑难题解算器,等等。
你可能会听说过:表格是非语义的。这并不正确 - 它们语义地指出了表格数据,当展示数据时表格是个很好的选择。
什么时候不使用表格
表格并不适用于布局。这看起来好像有点奇怪。那让我们看一下为何表格的特性使它们似乎适合用于布局:易于控制,逻辑严密,具有可预见性,并且一点也不脆弱。
但当使用表格来布局时有一些严重的问题。首先,HTML标签意味着某些东西。像我们前面提到的,table 元素语义地描述了列表式数据。把它们用于其他的任何东西都是违反语义化的职责的。虽然你在邮件中使用并不会受到惩罚,但在HTML文档中使用 table 的获益并没有这么大。
但谈论语义化有时候并不是那么简单(相关资料:1,2,3,4,5),因此我们来谈论一些所有人都基本同意的东西(即使我们没有像我们想达到地那么好):网站应该是可访问的。其中一部分的可访问性是面向屏幕读者而言。屏幕读者是从上至下从左至右地阅读表格的。因为你要根据表格的结构来决定如何呈现网站内容,也就意味着由视觉的选择而不是可访问性的选择决定。
说到资源顺序,它的影响超过了可访问性。想象一个“侧边栏在左边”的布局,一个表格会要求表格应该首先出现在资源序列中,这同时也不利于可访问性,也可能不利于SEO,这潜在地决定了你得辅助内容在你得主要内容之上。
你能通过在表格中使用语义化的标签来解决SEO的问题吗?这是有可能的,但你现在在使用双重HTML。如果你真的需要表格的布局能力但又想使用语义标签,那请看下一部分。如果你在使用 table 布局时不知道该如何达到语义化,请在表格中使用ARIArole="presentation"
表明它的含义。
当我在2013下半年后写这篇文章时,表格已经变得不那么流行并且在布局方案中也没有那么大的吸引力了。我们看到现在大量的人更多地使用固定或绝对定位,这在表格当中是无法做到的。我们看到 flexbox 在主流可用性的边缘成为极好的一个选择。我们看到网格布局开始发展起来。我们看到 inline-block 强大的使用方法。我们看到过去那浮动的脆弱性已经逐渐消失。
现在你已经很少看到现代网站使用表格来布局了,除了HTML邮件还在坚持以外。呈现邮件的范围是非常广阔的。邮件出现在互联网的任何地方和移动端的原生应用以及老式和新式系统的桌面端。你可以对邮件做些进步性的优化,但大家一致认为它最安全的布局方式是使用表格。一个有力的证据是:主要的邮件推送服务器全都用表格来搭建模板。
使语义元素表现地像一个表格
CSS中有一个属性能让任何元素表现地像一个表格元素。你需要从本质上改变它们因为你需要的是个表格,并且它会从属像表格一样的资源顺序的依赖关系。我不是在做什么无聊的事,因为它有时候是有很大作用的。如果这种布局风格解决了问题并不会再顺序上造成什么影响,你应该使用它。
请避免使用内联样式,但为了便于理解,这里就破例用了:
<section style="display: table;"> <header style="display: table-row;"> <div style="display: table-cell;"></div> <div style="display: table-cell;"></div> <div style="display: table-cell;"></div> </header> <div style="display: table-row;"> <div style="display: table-cell;"></div> <div style="display: table-cell;"></div> <div style="display: table-cell;"></div> </div> </section>
这儿一个方便的技巧是,如果你不希望的话,你甚至不需要表格行元素。这样的话,所有的display: table-cell
元素会作为display: table;
元素的子元素并且他们都在同一个表格行当中。
你总是需要改变元素的 display 属性来得到表格风格的行为,这里是它们的相关值:
display: table /* <table> */ display: table-cell /* <td> */ display: table-row /* <tr> */ display: table-column /* <col> */ display: table-column-group /* <colgroup> */ display: table-footer-group /* <tfoot> */ display: table-header-group /* <thead> */
注意这里没有<th>
的值,这是因为语义的关系,<th>
和<td>
的表现实际上是相同的,所以没必要多增加这样一个值。
这里还有一个相当有趣的值display: inline-table;
。记得我们前面谈论过的怪异的表格元素的宽度。表格是自适应宽度的。它就像 inline-block 元素一样。顾名思义,这个值使得它们成为一个 inline-block 元素而不会产生换行。
如果你想要了解更多的语义元素和表格风格布局,请查看Everything You Know About CSS Is Wrong!
我从来没有认可过这个标题因为该书建议过除了表格风格的布局其他的布局方法都是错误的。但正如我曾说过的,这种方法是非常有用的,它能在CSS中出现我感到非常开心。只是要意识到无论你使用什么样的元素来创建一个表格式的布局,它们都遵循一个相同的东西(资源顺序依赖关系)。
所有的表格相关元素
有几个元素在前面我们是没有提及的,让我们看看HTML表格的相关元素。这里我们也用一个表格来呈现它们:
Element | What it is |
---|---|
<table> |
The table itself |
<caption> |
The caption for the table. Like a figcaption to a figure. |
<thead> |
The table header |
<tbody> |
The table body |
<tfoot> |
The table footer |
<tr> |
A table row |
<th> |
A table cell that is a header |
<td> |
A table cell that is data |
<col> |
A column (a no-content element) |
<colgroup> |
A group of columns |
所有的表格相关属性
只有这么一点表格属性实在令人吃惊。当然你可以使用类和ID来使用你所需要的全局属性。以前表格拥有相当多的属性,但大多数都已经被废弃了。
Attribute | Element(s) Found On | What it does |
---|---|---|
colspan |
th, td | extends a cell to be as wide as 2 or more cells |
rowspan |
th, td | extends a cell to be as tall as 2 or more cells |
span |
col | Makes the column apply to more to 2 or more columns |
sortable |
table | Indicates the table should allow sorting |
headers |
td | space-separated string corresponding to ID's of the <th> elements relevant to the data |
scope |
th | row | col | rowgroup | colgroup (default) - essentially specifies the axis of the header. The default is that a header is heading a column, which is typical, but a row might start with a header also, where you would scope that header to the row or rowgroup. |
弃用的属性
不要使用它们的任何一个,它们已经被弃用了。尽管它们可能还可以起作用,但未来它们有可能会失效。
Deprecated Attribute | What to use instead |
---|---|
align | Use float property instead |
valign | Use vertical-align property instead |
char | The correct answer is to use text-align: "x"; where x is the character to align on, but it's not implemented anywhere yet. But this attribute isn't supported either, so no big loss. |
charoff | See above |
bgcolor | Use background property instead |
abbr | "consider starting the cell content by an independent abbreviated content itself or use the abbreviated content as the cell content and use the long content as the description of the cell by putting it in the title attribute" |
axis | Use the scope attribute instead |
border | Use border property instead |
cellpadding | Using padding property instead |
cellspacing | Use border-spacing property instead |
frame | Use border property instead |
rules | User border property instead |
summary | Use <caption> element instead |
width | Use width property instead |
表格的堆叠
表格元素有一个隐式的垂直堆叠方式,和HTML结构中父元素和子元素的关系相同。这个理解在表格中是相当重要的,因为在应用 background 之类的属性时,我们可以通过在表格或者表格行应用一种背景,再在单元格应用另一种背景来覆盖它。
这就是它的外貌(使用firefox浏览器开发者工具的3D特性呈现):
表格的重要样式规则
在表格元素上你可以使用大多数的CSS属性,font-family
在表格元素上的表现和在其他元素时一样,举个例子。如果我们层叠地应用此属性,在 table 元素中使用一种font-family
,在 table-cell 元素中使用另一种font-family
,文字会使用后一种样式,因为table-cell才是文字的最近父容器。
下面这些属性一些是特别地只能应用与表格元素的,一些则是在表格元素中有不同的特性。
CSS Property | Possible values | What it does |
---|---|---|
vertical-align | baseline sub super text-top text-bottom middle top bottom % length |
Aligns the content inside a cell. Works particularly well in tables, although only the top/bottom/middle make much sense in that context. |
white-space |
normal pre nowrap pre-wrap pre-line |
Controls how text wraps in a cell. Some data may need to be all on one line to make sense. |
border-collapse |
collapse separate |
Applied to the table to determine if borders collapse into themselves (sort of like margin collapsing only bi-directional) or not. |
border-spacing | length |
If border-collapse is separate , you can specify how far cells should be spaced out from each other. Modern version of cellspacing attribute. And speaking of that, padding is the modern version of the cellpadding attribute. |
width | length | Width works on table cells just about how you would think it does, except when there is some kind of conflict. For instance if you tell the table itself to be 400px wide then the first cell of a three-cell row to be 100px wide and leave the others alone, that first cell will be 100px wide and the other two will split up the remaining space. But if you tell all three of them to be 10000px wide, the table will still be 400px and it will just give each of them a third of the space. That's assuming white-space or elements like an image don't come into play. This is probably a whole post in itself! |
border | length |
Border works on any of the table elements and just about how you would expect. The quirks come in when you collapse the borders. In this case all table cells will have only one border width between them, rather than the two you would expect them to have (border-right on the first cell and border-left on the next cell). In order to remove a border in a collapsed environment, both cells need to "agree" to remove it. Like td:nth-child(2) { border-right: 0; } td:nth-child(3) { border-left: 0; } Otherwise, source order/specificity wins which border is shown on which edge. |
table-layout |
auto fixed |
auto is the default. The width of the table and its cells depends on the content inside. If you change this to fixed , the table and column widths are set by the widths of table and col elements or by the width of the first row of cells. Cells in subsequent rows do not affect column widths, which can speed up rendering. If content in subsequent cells can't fit, the overflow property determines what happens. |
以上的属性并不是很详尽,对表格来说还有一些属性的表现是怪异的,举个例子,你不能对单元格进行相对定位从而改变它的位置或者绝定位它的子元素。但可以通过别的办法来实现。
如果你想到了更多的有关表格的怪异现象,可以在下方评论区跟大家分享一下。
默认样式/User Agent样式表
Webkit内核的默认样式:
table { display: table; border-collapse: separate; border-spacing: 2px; border-color: gray } thead { display: table-header-group; vertical-align: middle; border-color: inherit } tbody { display: table-row-group; vertical-align: middle; border-color: inherit } tfoot { display: table-footer-group; vertical-align: middle; border-color: inherit } table > tr { vertical-align: middle; } col { display: table-column } colgroup { display: table-column-group } tr { display: table-row; vertical-align: inherit; border-color: inherit } td, th { display: table-cell; vertical-align: inherit } th { font-weight: bold } caption { display: table-caption; text-align: -webkit-center }
我在已经更换为Blink内核的Chrome浏览器的开发者工具中检查了这里面的每个元素,它们仍然是相同的。
有意思的是,在<th>
标签中的文本默认是居中的(text-align: center;
)。但这并没有被声明在UA样式表中。虽然并不是什么大不了的事情,但这让人感到有点神秘,让你还想知道更多在渲染的时候发生的其他神秘东西。
UA样式表在不同的浏览器中是各不相同的。举个例子,在firefox浏览器中(此处是 3.6的 UA 样式表, 但在v23里面也是正确的)单元格具有以下属性:
td { display: table-cell; vertical-align: inherit; text-align: inherit; padding: 1px; }
但在WebKit中,这1px的内边距是不存在的。虽然没有造成多大的区别,但它们确实是不一样。这就是CSS Reset(或者其他相似的东西)的作用:去除浏览器造成的差异。因此来让我们看看这个东西吧。
重置默认的表格样式
世界上最流行的CSS reset叫做 Meyer Reset,对表格做了如下设置:
table, caption, tbody, tfoot, thead, tr, th, td { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } table { border-collapse: collapse; border-spacing: 0; }
它的做法和 HTML5 Reset 以及 HTML5 (Doctor) Reset Stylesheet 是相同的。
这还有一个可供选择的 CSS resets,Normalize.css 。它的重置的原理有一点儿不同。它没有将所有的样式重置为0,而是设置一些合理的不一致的样式。我对使用 Normalize.css 的建议是:不要移除里面的任何东西。但可以自由地修改它们。
Normalize 对表格只做了如下样式设置:
table { border-collapse: collapse; border-spacing: 0; }
我好像需要更深入地研究,因为我觉得上面的样式有点不寻常......
- 我很喜欢使用
border-collapse: collapse
,因为单元格之间的空隙会让人感到有点尴尬,但我知道在所有的浏览器中都是如此的border-collapse: separate;
,所以它并不需要被归一化。 - 如果
border-collapse
的值是collapse
,那么border-spacing
是无关紧要的。 - 单元格元素时需要进行归一化的(例如在firefox和chrome中的padding是不同的),但这里却没有这么做。
这些东西不会有太大影响,也不必纠结。
对我来说,通常我会对表格进行下面的重置:
table { border-collapse: collapse; 100%; } th, td { padding: 0.25rem; text-align: left; border: 1px solid #ccc; }
“隐含”元素和未关闭的标签
看看下面丑陋的HTML:
<table> <col> <tr> <td>Cell </table>
虽然看起来有点怪异,但它是起作用的。为什么会这样?
<col>
标签是属于那种无内容的不需要闭合的标签,类似<br>
/<br />
<td>
元素在这些情况中是无需闭合的:“如果<td>
元素后面没有更多的<td>
或<th>
元素或者在它父元素中没有更多的内容,闭合标签是可以省略的。”- 缺少的
</tr>
标签的原理也是相同的:“如果<tr>
元素后面没有紧跟着一个<tr>
元素或者如果它父元素组(<thead>
,<tbody>
或者<tfoot>
)没有更多的内容,结束标签是可以省略的。”
如果我们检查浏览器对表格的渲染,我们可以看到那些缺少了闭合标签的标签又重新拥有了闭合标签。这是浏览器自动为我们添加的。并且里面还增加了一些新的元素。
要注意到的是,<col>
元素被一个自动添加的<colgroup>
元素所包裹。
甚至如果我们这样做:
<table> <col> <colgroup> <col> </colgroup> <tr> <td>Cell <td>Cell </table>
然后:
colgroup:first-child { background: red; }
你可能会认为第二个单元格会变成红色,而不是第一个。因为这里的“第一个” colgroup 仅会影响第二个单元格。但在渲染的时候却发现,两列都被包裹在 colgroup 当中,因此CSS选择器会选择第一个。
<tbody>
元素也是隐含的。如果你不使用任何的 tbody,thead 或 tfoot,那么整个表格的内容都会被包裹在 tbody 当中(实际上被包裹的只有表格行和其子元素, col 和 colgroup 并不会被包含)。如果你使用 thead 那么整个表格会包裹在它里面直到找到 tbody (但在我的测试下并不是这样子,thead并不会包含任何元素,不知道是否作者笔误),然后它会自动关闭 thead 标签。
你可以在CSS选择器中使用这些隐含的元素即使你没有将它写在HTML当中。但我并不建议这样做,因为这样的HTML是相当丑陋和让人迷惑的。通常也是不建议使用标签选择器进行样式设置。
使表格变为非表格元素
在一些情况下你可能会需要强制让表格不应用它的表格形式的布局行为而更像一些其他的规则元素。
这只是个通过改写单元格的 display 属性来实现的技巧:
th, td { display: inline; }
我们可以相当快速地去表格化一个表格:
为了安全起见,我对所有表格相关元素进行了重置。因为这个我会知道这下父元素不会对我的测试造成什么影响了。
table, thead, tbody, tfoot, tr, td, th, caption { display: block; }
这在响应式布局中相当地有用,因为传统的表格布局从大屏幕转移到小屏幕时需要做显著的改变以保持布局的完整。
表格可访问性
我们已经谈论过使用表格来布局以及表格的可访问性了。但假设表格已经被正确地用于表格数据了,仍然有许多值得关注的可访问性问题。
这里有几篇很好的相关文章:
- WebAIM: 创建可访问的表格
- Portland Community College: 对屏幕读者而言的优秀的和劣质的表格布局例子
- Web Usability: 易于访问的表格数据
斑马条纹表格
如果你不为表格单元设置背景颜色,你可以为它们的所属的表格行设置背景色,所以最简单地,你可以这样做:
tbody tr:nth-child(odd) { background: #eee; }
我们在选择器的 tr 前面增加了 tbody,因为你不太会希望为表格的 header 和 footer 中的表格行添加条纹。你也可以改变偶数行的背景颜色来突出它们,如果你想的话。
如果你想要支持那些不支持 :nth-child() 的浏览器(相当该死),你可以使用 JQuery 来实现。
调查似乎显示添加斑马条纹是个不错的注意。
高亮行与列
特别地高亮某一行是相当简单的,你只需要为该行添加一个类来指定它就可以了:
<tr class="highlight"> ... </tr>
列的高亮有点儿棘手,一个可行的办法是使用<col>
元素,它可以让我们为出现在那一列中的表格设置属性。这可能会让你有点迷糊,因为受到影响的表格并不是<col>
实际的后代元素。
一个拥有4个列的表格在每一行都会有4个<col>
元素:
<table> <col> <col> <col> <col> <thead> ... </table>
然后你可以高亮特定的一列,如:
col:nth-child(3) { background: yellow; }
然而很少人会这样使用。如果你为某一行或某个单元格设置背景色,它总是会覆盖如上设置的某一列背景色。
你可能最好能为指定的某列的每一个单元格设置一个类,如:
td:nth-child(2), th:nth-child(2){ background: yellow; }
高亮鼠标所在的行/列/单元格
单元格的高亮是非常简单的,你可以通过下面的CSS设置:
td:hover { /* th:hover also if you wish */ background: yellow; }
行的高亮也相当简单。你可以设置鼠标所在的表格行的背景色,这样只要鼠标经过背景色便会改变,但前提是你不设置单元格的背景色。
tbody tr:hover { background: yellow; }
如果你设置了单元格的背景色,你也可以通过tr:hover td, tr:hover th { }
来达到同样的效果,也还是相当简单的。
列的高亮有点儿麻烦,你不能使用col:hover
来实现,因为这个列元素并不是实际的占据了像素空间的元素,因此鼠标也无法悬浮到该元素上。唯一的方法就是通过Javascript来实现。
它的工作方式如下:
- 得到一个所有单元格的集合。
- 绑定 mouseover 和 mouseout 事件到每一个单元格元素。
- 当 mouseover 事件触发时,得到单元格在该行中的位置。
- 遍历所有的行,并为每一行的那个位置的单元格添加一个高亮类。
- 当 mouseout 事件触发时,移除所有单元格的高亮类。
下面我在一个例子中结合使用了行和列的高亮,我使用jQuery使JS代码减少到12行(原生JS太过费劲)。
但实现的原理是相同的,只不过使用jQuery可以更快地得到元素的集合,并能快速的得到单元格在行中所处的位置。
样式美化后的表格
一些深度,视觉上不同的标题,和一个终端匹配的标题。
当表格被鼠标悬浮时,只有当前高亮行的文本时保持黑色的,其他行的文本颜色淡化处理。另外记住一点:表格自身设置圆角时需要设置border-collapse: separate;
这里是另外一个在non-hovered行进行模糊处理的例子:
Twitter Bootstrap 的表格样式非常简单:
这一个,作为奖励,还具有键盘控制:
我一直努力保持收集精心设计的表格的习惯以便作为参考。因此如果你发现了任何精美的表格,请与我分享。Hong Kiat 也有一个精美表格集合。
表格搜索
虽然表格的排列相当困难,但表格的搜索却非常容易。增加一个搜索输入,如果那里的值匹配到了任意一行的文本,则显示该行,并隐藏其他所有的行。使用jQuery来实现就像下面这么简单:
var allRows = $("tr"); $("input#search").on("keydown keyup", function() { allRows.hide(); $("tr:contains('" + $(this).val() + "')").show(); });
这是使用正则表达式来实现的版本:
这是原生JS实现的版本:
表格在流体/响应式设计中会有点难以处理
我过去已经写过这方面的文章,并且我认为这个图形能让你了解到数据表在小屏幕中的体验是怎样的。
我最终对过去的各式各样的解决方案做了一个综述。
真正快速的方法:
- 将行变成块(1)(2)
- FooTable - 一个通过切换图标来隐藏行和使数据可用的jQuery插件
- 将数据转换成图表
- 通过隐藏列来节省空间并允许用户切换那些隐藏的列
- 压缩单元格并让它们被包裹
- 固定表头部分并使数据区的内容可滚动(1)(2)(3)
下面是两个不同风格和需求的实体例子:
固定表头
这也是我以前写过的东西并且还做了一小段视频。这些东西都已经有一段历史了,但这些案例还是能使用的。
最现代的固定表头的办法是position: sticky;
,这儿有一篇相关的文章。老实说我并不确定这个推荐的方法是否可行。在正常情况下它无法在中起作用。这还是有点意义的因为你无法在表格里面进行绝对定位子元素。但它在<th>
当中是起作用的。不管怎样,如果有人想把它弄清楚,这会是对这篇文章的一个很好的更新。
这里是使用 jQuery 插件实现的一个例子:
使用 Emmet 来创建表格标签
有一大堆的理由可以说明 Emmet 是个好工具,其中一个就是可以用它来书写缩略的 HTML 然后再一键拓展为真正的 HTML,因为表格通常都是重复性比较高并且很冗长的。 Emmet 对它来说实在是太适合了,Emmet 还能在 CodePen 运行呢。=)
简单的4行4列
table>tr*4>td*4
5行并且包含左侧标题信息
table>tr*5>th+td*4
一行并包含上方标题信息
table>tr>th*5^tr*3>td*5
具有自增ID的员工信息表
table>tr>th{Name}+th{ID}+th{Favorite Color}^tr*3>td{Name}+td{$$$$$}+td{Blue}
包含头部尾部和内容的表格
table>thead>tr>th{Header Cell}*5^^tfoot>tr>th{Footer Cell}*5^^tbody>tr*10>th{Row Header}+td{Cell Data}*4
Javascript生成表格
Javascript通过HTMLTableElement
API提供了非常明确的用于处理表格的方法。Louis Lazaris最近写了一些关于这方面的东西。你可以通过阅读它来使用JS生成表格,访问子元素,以及用特别的方法来改变属性。这是MDN站上的相关资料。
下面是给出的例子:
表格排序
假设现有一个具有两列的表格。一列用于记录员工的ID,另一列用于记录员工的email地址。每一列上方都有一个标题。可以通过点击标题来对该列的数据进行排序。举个例子,ID以数值进行排序,邮件地址以字母进行排序,两者可以进行升序和降序的切换。这就是表格排序,能够使数据起更大的作用。
这是一个相当常用的需求,这还有一份为其准备的说明书。只要将sortable
属性放进 table 当中,它便会自动地排序只要遵循说明书中的几条规则。
在写下这篇文章的时候,我不知道是否有任何的浏览器支持表格的原生排序。但这还有提供了三个额外的实现方法!
- tablesorter - 基于jQuery的 "灵活的客户端表格排序"
- sorttable - 原生 javaScript
- tablesort - "一个精简的应用于表格排序的组件。原生 Javascript 实现,没有其他的依赖。"
下面是表格排序的例子:
如果上面这些并没有帮助到你,Codrops 收集的33中表格排序脚本,可以给予你更多的选择。
这些都是 Javascript 的解决方法。也可以通过在后端进行排序然后将排序好的数据直接在前端呈现。这个方法可以用在:在分页表格中,当DOM中的所有数据并不是马上可用的时候。
更多信息
译者手语:整个翻译依照原文线路进行,并在翻译过程略加了个人对技术的理解。如果翻译有不对之处,还烦请同行朋友指点。谢谢!
白牙
互联网开发者,关注Web应用开发,前端交互设计。个人博客,多多交流,愿与大家共同进步。
如需转载烦请注明出处:
英文原文:http://css-tricks.com/complete-guide-table-element/
中文译文:http://www.w3cplus.com/css/complete-guide-table-element.html