HTML 表格元素指南

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 $200 免费积分!

HTML 中的 <table> 元素用于显示表格数据。 可以将其视为一种描述和显示在电子表格软件中具有意义的数据的方式。 基本上:列和行。 在本文中,我们将探讨如何使用它们,何时使用它们以及您需要了解的有关表格元素的所有其他信息。

一个非常基本的例子

这是一个非常简单的表格数据的演示

这些数据在多个轴上都有用。 想象一下,沿着一行(水平)滑动手指以查看单个人员及其相关信息。 或者沿着一列(垂直)上下滑动以了解该点上数据的多样性或模式。

头部和主体

我们在上面的基本示例中没有做的一件事是语义地指示第一行是表格的标题。 我们可能应该这样做。 整个第一行不包含任何数据,它只是列的标题。 我们可以使用 <thead> 元素来实现这一点,它将包装第一个 <tr>(它可以包装尽可能多的行,这些行都是标题信息)。

该 HTML 代码将如下所示

当您使用 <thead> 时,不能有任何 <tr><table> 的直接子元素。 所有行必须位于 <thead><tbody><tfoot> 中。 请注意,我们还将这里的所有数据行包装在 <tbody> 中。

除了 <thead><tbody> 之外,还有 <tfoot> 用于包装指示表格脚注的表格行。 与 <thead> 一样,最适合语义地指示这些不是数据行,而是辅助信息。

回到 HTML5 之前<tfoot> 元素必须在 <thead> 之后且 <tbody> 之前! 您可能认为它应该是 <table> 结束之前的最后一件事,但事实并非如此。 现在在 HTML5 中,情况恰恰相反,它必须在 <tbody> 之后,就像您可能期望的那样。

例如,它可以用来在表格非常高/很长的情况下重复标题,在这种情况下,在底部看到列标题可能比在顶部更容易。 虽然您不一定需要以这种方式使用它。

单元格:tdth

表格的各个单元格始终是以下两个元素之一:<td><th>。 您可以在表格单元格中放入任何内容,但这些元素使它们成为表格单元格。 <th> 元素是“表格标题”,而 <td> 元素是“表格数据”。

使用我们现有的简单演示,顶行都是标题。 不是数据,只是数据的标题。 所有其他行都是数据。 所以

<th> 元素不一定要位于 <thead> 内。 它们只是指示标题信息。 因此,例如,它们可以在 <tbody> 中一行开头使用,如果相关的话。 我们将在后面介绍类似的情况。

基本样式

您遇到的多数表格都使用颜色和线条来区分表格的不同部分。 边框非常常见。 默认情况下,所有表格单元格都通过 2 像素(通过用户代理样式表)相互间隔,如下所示

请注意第一行与其余行之间略微的额外间隙。 这是由于将默认的边框间距应用于 <thead><tbody>,导致它们彼此稍微分离。 这不是边距,它们不会折叠。 您可以像这样控制该间距

table {
  border-spacing: 0.5rem;
}

常见的是删除该间距。 如果您这样做,该属性将被完全忽略,间距也会被折叠

table {
  border-collapse: collapse;
}

只需一点填充、边框并将这些 <th> 元素左对齐,就能使一个简单的样式表格大放异彩

连接单元格

在任何表格单元格元素(<th><td>)上都可以使用两个重要的属性:colspanrowspan。 它们接受任何大于或等于 2 的正整数。 如果一个 td 的 colspan 为 2(即 <td colspan="2">),它仍然是一个单元格,但它将在水平方向上占据两个单元格的空间。 rowspan 类似,但作用在垂直方向上。

当您开始使用连接的单元格时,您需要进行一些简单的算术运算。 Colspan 相对容易。 任何表格单元格都“值” 1,除非它具有 colspan 属性,在这种情况下,它“值”为该属性的值。 将该表格行中每个表格单元格的值加起来以获得最终值。 每一行都应该恰好具有该值,否则您将得到一个不形成矩形的尴尬表格布局(最长的行将突出)。

Rowspan 类似,只是有点难,需要更多地思考,因为列不像行那样分组。 如果表格元素具有 rowspan 属性,它将在垂直方向上跨越两行。 这意味着它下面的行在表格单元格计数方面加 1,并且需要少一个表格单元格来完成该行。

用脑子想很难理解,但我们是开发者,我们可以做到 =)。

通常,这些属性以非常简单的方式使用,例如连接一些相关的表格标题

尽可能宽… 或者填充容器… 或者超出

表格元素本身在宽度方面不同寻常。 它表现得像块级元素(例如 <div>),如果您将一个表格放在另一个表格之后,每个表格都会断开并显示在自己的行上。 但是表格的实际宽度仅与其需要的一样宽。

如果表格中最宽行的文本量恰好是 100 像素宽,那么该表格将是 100 像素宽。 如果文本量(如果放在一行上)将比容器宽,它将换行。

但是,如果文本被告知不要换行(即 white-space: nowrap;),表格很乐意冲出容器并变得更宽。 表格单元格也不会换行,因此如果表格单元格过多而无法容纳,表格也会变得更宽。

双轴表格

有时,表格数据具有两个轴是有意义的。 例如,交叉引用情况。 乘法表就是一个例子

在这种情况下,我可能会跳过 <thead>,即使第一行都是标题。 它与垂直标题列一样重要,因此将第一行单独分组感觉很奇怪。 只需制作一行全部为 <th>,然后将每个后续行的第一个单元格设置为 <th>

何时使用表格

现在是休息一下并讨论表格何时使用的好时机。 也许您已经听说过一般的建议:表格用于表格数据(参见本文的第一句话)。 “这在电子表格中是否合理?” 测试通常是合适的。

表格中适合放置哪些内容?以下是一些示例:计划/定价/功能比较、保龄球得分、内部员工数据网格、财务数据、日历、营养成分信息面板、逻辑谜题求解器等等。

你可能偶尔会听到:“表格是无语义的”。这是不正确的——它们在语义上表示表格数据。当情况属实时,表格是正确的选择。

何时不使用表格

表格不适合用于布局。这可能看起来违反直觉。乍一看表格的工作原理,它们似乎是布局的理想选择。易于控制、极其逻辑、可预测,而且一点也不脆弱。

但是,使用表格进行布局有一些重大问题。首先,HTML 标签代表着意义。正如我们所述,表格元素在语义上描述了表格数据。将它们用于其他任何目的都是违反语义职责的行为。你不会收到罚单,但你无法从 HTML 中获得应有的价值。

谈论语义有时有点困难(有些读物:12345),所以让我们谈论一下我们普遍认同的事(即使我们没有达到理想水平):网站应该易于访问。可访问性的一部分是屏幕阅读器。屏幕阅读器从上到下、从左到右读取表格。这意味着网站呈现的顺序由表格结构决定,而表格结构由视觉选择而不是可访问性选择决定。更不用说,屏幕阅读器甚至可能宣布表格数据的开始,这比毫无用处更糟糕。

说到源代码顺序,它影响的不仅仅是可访问性。想象一个“左侧边栏”布局。表格将规定表格在源代码顺序中排在首位,这不仅对可访问性不利,而且可能对 SEO 也不利,因为它可能会将辅助内容置于主要内容之上。

你可以通过在表格标签中使用语义标签来解决 SEO 问题吗?也许在某种程度上可以,但现在你使用了两倍的 HTML 代码。如果你真的需要表格的布局能力,但又想使用语义标签,请参阅下一节。如果你真的无法摆脱使用表格标签进行布局,请在表格上使用 ARIA 的 role="presentation" 来指示这一点。

当我写下这篇文章的时候,已经是 2013 年下半年了,表格作为布局选择的流行度和吸引力都已大不如前。我们看到更多地使用了固定定位和绝对定位,而你无法在表格内使用这些定位。我们看到 Flexbox 非常棒,并且正处于主流可用性的边缘。我们看到网格布局开始成熟。我们看到内联块的使用越来越强大。我们看到过去浮动元素的脆弱性正在消失。

现代网站很少使用表格进行布局。最后一道防线是 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>

这里一个方便的技巧是,如果你不想使用,甚至不需要 table-row 元素。一组 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> 的替代方案。这仅用于语义价值。在其他方面,它的行为与 <td> 相同,因此,无需在 CSS 中复制它。

还存在 display: inline-table;,这很有趣。还记得我们上面谈论过表格元素的宽度有多奇怪吗?它们只有在必要时才会变宽,但会换行。这就像它们是内联块元素,恰好会换行一样。这使它们实际上就像内联块元素,只是不会换行。

如果你想更多地了解如何使用语义元素,但同时也使用表格样式布局,请查看书籍 Everything You Know About CSS Is Wrong!

我一直不太喜欢这个标题,因为它暗示使用这种表格样式布局是正确的方式,而你使用的任何其他布局技术都是错误的方式。但正如我所说,这非常有用,我很高兴它存在于 CSS 中。只是要清楚地意识到,无论你使用什么类型的元素来创建表格式布局,它仍然会遇到相同的问题(主要源代码顺序依赖性)。

上面有一些元素我们还没有涉及。让我们看一下所有与 HTML 表格相关的元素。你知道吗,我们可以用表格来做这件事

元素它是什么
<table>表格本身
<caption>表格的标题。就像 figcaption 对于 figure 一样。
<thead>表格标题
<tbody>表格主体
<tfoot>表格页脚
<tr>表格行
<th>作为标题的表格单元格
<td>作为数据的表格单元格
<col>列(无内容元素)
<colgroup>一组列

令人惊讶的是,很少有属性是专门针对表格的。当然,你可以使用类和 ID 以及所有典型的 全局属性。以前有很多这样的属性,但大多数是针对样式的,因此被弃用了(因为那是 CSS 的工作)。

属性它所在的元素它的作用
colspanth, td将单元格扩展为 2 个或更多个单元格的宽度
rowspanth, td将单元格扩展为 2 个或更多个单元格的高度
spancol使列应用于 2 个或更多个列
sortabletable指示表格应该允许排序。更新:据我所知,由于缺乏实现,该属性已从规范中删除。
headerstd与数据相关的 <th> 元素的 ID 的空格分隔字符串
scopethrow | col | rowgroup | colgroup(默认值)——基本上指定标题的轴。默认情况下,标题是列的标题,这很典型,但行也可能以标题开头,在这种情况下,你将该标题的范围设置为行或行组。

已弃用的属性

不要使用任何这些属性。它们已被弃用。虽然它们可能在当今的某些浏览器中仍然有效,但将来它们可能会停止工作。

已弃用的属性替代方案
align使用 float 属性
valign使用 vertical-align 属性
char正确的答案是使用 text-align: "x";,其中 x 是要对齐的字符,但它尚未在任何地方实现。但此属性也不受支持,因此损失不大。
charoff见上文
bgcolor使用 background 属性
abbr“考虑以独立的缩写内容本身开始单元格内容,或者使用缩写内容作为单元格内容,并将长内容作为单元格的描述,将其放在 title 属性中”
axis使用 scope 属性
border使用 border 属性
cellpadding使用 padding 属性
cellspacing使用 border-spacing 属性
frame使用 border 属性
rules使用 border 属性
summary使用 <caption> 元素
width使用 width 属性

表格堆栈

表元素之间存在隐含的垂直堆叠,就像任何 HTML 父元素 > 子元素场景中一样。在表格中理解这一点很重要,因为将背景应用到表格本身或表格行可能特别诱人,但表格单元格的背景会“覆盖”它(实际上它只是位于最上面)。

以下是它在 Firefox 中的外观(使用其开发工具中的 3D 功能)

表格的重要样式规则

您可以在表元素上使用大多数 CSS 属性。例如,font-family 在表格上的工作方式与在任何其他元素上的工作方式相同。并且级联规则适用。将 font-family 应用于表格,但将不同的 font-family 应用于表格单元格,表格单元格将获胜,因为它是包含文本的实际元素。

这些属性要么是表格元素独有的,要么是在表格元素上表现出独特的行为。

CSS 属性可能的值它的作用
vertical-alignbaseline
sub
super
text-top
text-bottom
middle
top
bottom
%
length
对齐单元格内部的内容。在表格中特别有效,尽管在这种情况下只有顶部/底部/中间有意义。
white-spacenormal
pre
nowrap
pre-wrap
pre-line
控制文本在单元格中的换行方式。某些数据可能需要全部在一行上才能有意义。
border-collapsecollapse
separate
应用于表格以确定边框是否会折叠到自身(有点像边距折叠,只是双向的)或不折叠。如果两个折叠在一起的边框具有冲突的样式(例如颜色)怎么办?应用于这些类型元素的样式将按“强度”顺序“获胜”:单元格、行、行组、列、列组、表格。
border-spacinglength如果 border-collapseseparate,则可以指定单元格之间的间距。cellspacing 属性的现代版本。说到这个,paddingcellpadding 属性的现代版本。
widthlengthWidth 在表格单元格上的工作方式几乎与您想象的一样,除非存在某种冲突。例如,如果您告诉表格本身的宽度为 400px,然后告诉三单元格行的第一个单元格的宽度为 100px,并让其他单元格保持不变,那么第一个单元格的宽度将为 100px,另外两个将分割剩余的空间。但是,如果您告诉所有三个单元格的宽度为 10000px,表格的宽度仍然为 400px,它只会给每个单元格分配三分之一的空间。假设 white-space 或图像等元素不会发挥作用。这可能需要单独发一篇文章!
borderlengthBorder 在所有表格元素上的工作方式几乎与您预期的一样。当您折叠边框时,就会出现怪异之处。在这种情况下,所有表格单元格之间只会有一个边框宽度,而不是您预期的两个(第一个单元格的 border-right 和下一个单元格的 border-left)。为了在折叠环境中删除边框,两个单元格都需要“同意”删除它。例如 td:nth-child(2) { border-right: 0; } td:nth-child(3) { border-left: 0; } 否则,源顺序/特异性将决定哪个边框显示在哪个边缘。
table-layoutauto
fixed
auto 是默认值。表格及其单元格的宽度取决于内部的内容。如果您将其更改为 fixed,表格和列的宽度将由表格和 col 元素的宽度或第一行单元格的宽度设置。后续行的单元格不会影响列的宽度,这可以加快渲染速度。如果后续单元格中的内容无法容纳,则 overflow 属性将决定会发生什么。

此列表并不详尽。还有其他与表格相关的 CSS 问题。例如,您不能相对定位表格单元格以将其微调或在其中绝对定位内容。 不过有一些方法。

如果您能想到表格中更多与 CSS 相关的怪异之处,请在下面的评论中分享。

默认样式/用户代理样式表

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
}

我也在 Chrome 开发工具中检查了每个元素,现在它在 Blink 上,仍然相同。

不过很有趣。当然,<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 重置(以及相关项目)的意义所在:消除差异。所以让我们来看看它们。

重置默认表格样式

世界上最流行的 CSS 重置,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 ResetHTML5(Doctor)重置样式表 中也是这样做的。

不过,CSS 重置有一个替代方法,那就是 Normalize.css。其理念略有不同。它不是将所有样式都设置为零,而是专门将已知不一致的样式设置为合理的默认值。我使用 Normalize.css 的一般建议是:不要从中删除任何内容。如果它在那里,那是为了确保一致性。但可以随意更改其中的任何内容。

Normalize 只对表格做了以下处理

table {
  border-collapse: collapse;
  border-spacing: 0;
}

我需要更深入地研究一下原因,因为它似乎不寻常……

  1. 我喜欢 border-collapse: collapse,因为单元格之间的间距通常很尴尬,但是,我知道的所有浏览器中的默认值都是 border-collapse: separate;,因此不需要规范化。
  2. 如果 border-collapsecollapseborder-spacing 就不起作用。
  3. 表格单元格元素需要规范化(例如 Firefox 填充差异),但这里没有。

这不是什么大问题。

这正是我通常会做的事情

table {
  border-collapse: collapse;
  width: 100%;
}
th, td {
  padding: 0.25rem;
  text-align: left;
  border: 1px solid #ccc;
}

“隐含”元素和未闭合标签

看看这段相当奇怪的 HTML 代码

<table>
  <col>
  <tr>
    <td>Cell
</table>

这可能看起来很奇怪,但它是有效的。这里发生了什么?

  • <col> 标签只是那些不包含内容的元素之一,永远不需要闭合标签。就像 <br> / <br />
  • <td> 元素在某些情况下不需要闭合:“如果紧随其后的是 <th><td> 元素,或者如果其父元素中没有更多数据,则可以省略结束标签。”
  • 缺少的闭合 </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 中。如果您使用 thead,整个表格将被包装在其中,直到找到 tbody,然后,如果您不闭合它,它会自动闭合 thead,并将剩余部分包装在 tbody 中(也可以选择闭合)。如果它找到 tfoot,您可以想象会发生什么(但请记住 tfoot 应该放在 tbody 之前)。

您实际上可以在 CSS 选择器中使用这些元素,即使您没有将它们放到实际的 HTML 中。我可能不建议这样做,因为这很奇怪,很令人困惑,而且样式标签选择器通常也不建议使用。

将表格变成非表格

总有一天,您可能会遇到需要强制表格元素不表现出其表格样式布局行为,而表现得更像普通元素的情况。

诀窍是 essentially to reset the display property of the table cells

th, td {
  display: inline;
}

我们可以很快地将表格变成非表格

为了安全起见,我建议重置整个系统。这样会让我感觉更好,因为父元素也会一起重置,不会出现意外情况。

table, thead, tbody, tfoot, tr, td, th, caption {
  display: block;
}

这在响应式设计中非常有用,因为传统的表格布局在大屏幕上很有意义,但在小屏幕上需要进行重大调整才能正常显示。下面有一节专门讨论这个问题。

表格无障碍性

我们已经讨论过使用表格进行布局和无障碍性的问题。但假设表格是正确用于表格数据的,仍然存在一些无障碍性问题。

关于这个问题,有一些非常棒的文章。

表格斑马条纹

如果你没有在表格单元格元素上设置背景颜色,你可以在表格行本身设置。因此,最基本的方法是

tbody tr:nth-child(odd) {
  background: #eee;
}

我们在选择器中使用 `tbody`,因为你不太可能想要为表头和表尾行添加条纹。如果你想明确指定,而不是让下面的内容透出来,可以设置偶数行。

如果你需要支持不支持 `:nth-child()` 的浏览器(非常古老),你可以使用 jQuery 来实现

研究表明,斑马条纹通常是一个好主意。

突出显示行和列

突出显示特定行非常容易。你可以为此特定行添加一个类名。

<tr class="highlight">
  ...
</tr>

突出显示列比较棘手。一种方法是使用 `<col>` 元素,它允许我们为出现在该列的单元格设置样式。这有点难以理解,因为受 `<col>` 影响的单元格实际上不是它的子元素。浏览器只是知道你的意思。

一个表格,每行有四列,将有四个 `<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。

我在纯 JavaScript 中编写了它,只是为了好玩。

它的工作原理如下:

  1. 获取所有单元格的集合。
  2. 将鼠标悬停和鼠标移出事件绑定到所有这些单元格。
  3. 当鼠标悬停事件触发时,获取该单元格在行中的位置。
  4. 循环遍历所有行,将突出显示类添加到与该位置匹配的每行中的每个单元格。
  5. 当鼠标移出事件触发时,从所有单元格中删除突出显示类。

在这里,我将行和列突出显示都组合在一起。我使用了 jQuery 来将所有代码缩减为 12 行(纯 JavaScript 代码正在变得相当冗长)。

概念相同,只是在 jQuery 中创建元素集合,以及通过索引查找和选择更容易。

精美样式的表格

一些深度,视觉上不同的表头,以及与表头匹配的终端。


当鼠标悬停在表格上时,只有当前突出显示的行保持深色文本,其他行恢复淡化。请注意,只有在 `border-collapse: separate;` 时,表格本身的圆角才有可能。


这是另一个示例,其中未悬停的行会模糊。


Twitter Bootstrap 的表格样式非常简洁。


此外,它还支持键盘控制!


我尝试维护 一个精心设计的表格集合 供参考。如果你有好的表格,请告诉我。洪基亚特也有一篇 博客文章集合

表格排序可能很复杂,但表格搜索非常简单。添加一个搜索输入框,如果其中输入的值与某行中的任何位置的文本匹配,则显示该行,并隐藏其他行。使用 jQuery,这可能和下面一样简单。

var allRows = $("tr");
$("input#search").on("keydown keyup", function() {
  allRows.hide();
  $("tr:contains('" + $(this).val() + "')").show();
});

这里有一个使用 RegExp 的示例。

这里有一个纯 JavaScript 的示例。

表格在流体/响应式设计中可能很困难

我过去 写过这方面的内容,我认为这张图很好地概括了数据表格在小屏幕上的体验。

我最终 创建了一个汇总,因为出现了各种有趣的解决方案。

简单地说一下。

这里有一些带不同风格的实时演示。

固定表头表格

这也是我过去 写过 并做了一些 视频教程 的内容。这些教程比较古老,但 演示仍然有效

处理固定表头最现代的方法是 `position: sticky;`。这里有一篇 关于此方法的文章。说实话,我不太确定如何在表格中推荐使用它。它在正常情况下不适用于 `<thead>`。这有一定道理,因为你不能绝对定位表格内部元素。但它确实适用于 `<th>`。总之,如果有人愿意解决这个问题,这将是对本文的一个很好的更新(或其他内容)。

这里有一个 jQuery 插件的实时演示,它可以解决这个问题。在目前情况下,我会选择使用类似这样的方法,直到 sticky 方法更加完善。

使用 Emmet 创建表格标记

Emmet 是一款很棒的工具,原因有很多。其中之一就是编写 HTML 缩写 并将其扩展成真正的 HTML。由于表格非常重复且冗长,因此 Emmet 非常适合它们。Emmet 也适用于 CodePen =)

简单的四行四列

table>tr*4>td*4

五行,标题在左边

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*5^^tfoot>tr>th*5^^tbody>tr*10>th+td*4

相同,但在每个单元格中都有单元格内容

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 最近写了一点关于它。你可以用它用 JavaScript 创建表格,访问子元素,并以非常特殊的方式改变属性。这是 MDN 页面,包含了所有信息。

这就是它在工作中

表格排序

想象一个有两列的表格。一列是员工 ID,另一列是员工电子邮件地址。每列都有标题。能够点击这些标题并根据里面的数据对表格进行排序会很方便。例如,对于 ID,可以按数字顺序排序,在升序和降序之间交替,而对于电子邮件地址,则可以按字母顺序排序。这就是表格排序的意义所在。让数据更有用。

这是一个如此常见且通用的需求,实际上有一个 为它准备好的规范。只需在表格上放置 sortable 属性,只要你遵循规范中列出的几个规则,它就会自动完成排序。

更新 2019 年 6 月:删除链接,它不再提到可排序。目前看来规范已经失效。

在撰写本文时,我不知道有任何浏览器原生支持表格排序。但有很多第三方选项!

  • tablesorter – 基于 jQuery 的“灵活的客户端表格排序”
  • sorttable – 纯 JavaScript
  • tablesort – “一个用于表格的小巧而简单的排序组件。用 Javascript 编写,无需依赖”

表格排序脚本和大小写有什么关系?无论如何,这是一个 tablesorter 的演示

如果这些对你不起作用,Codrops 收集了 33 种不同的表格排序脚本,所以有很多选择。

所有这些都是 JavaScript 解决方案。当然也可以在后端对数据进行排序,并在 HTML 中显示已排序的表格。这可能需要在分页表格中使用,因为并非所有数据都可以在 DOM 中直接使用。

更多信息