HTML 表格基础

本文将引导您开始使用 HTML 表格,涵盖非常基础的内容,例如行、单元格、标题、使单元格跨越多列和多行,以及如何将一列中的所有单元格组合在一起以进行样式设置。

先决条件 HTML 基础知识(请参阅 HTML 简介)。
目标 获得对 HTML 表格的基本熟悉。

什么是表格?

表格是一组结构化的数据,由行和列组成(**表格数据**)。表格允许您快速轻松地查找指示不同类型数据之间某种关联的值,例如人和他们的年龄,或一周中的某一天,或当地游泳池的时间表。

A sample table showing names and ages of some people - Chris 38, Dennis 45, Sarah 29, Karen 47.

A swimming timetable showing a sample data table

表格在人类社会中非常常见,并且已经存在很长时间了,正如 1800 年的这份美国人口普查文件所证明的那样

A very old parchment document; the data is not easily readable, but it clearly shows a data table being used.

因此,毫不奇怪,HTML 的创建者提供了一种方法来构建和呈现 Web 上的表格数据。

表格是如何工作的?

表格的重点在于它很严格。通过在行和列标题之间建立视觉关联,可以轻松地解释信息。例如,查看下面的表格并找到一颗具有 62 颗卫星的木星气态巨行星。您可以通过关联相关的行和列标题找到答案。

如果正确实现,HTML 表格会被屏幕阅读器等辅助功能工具很好地处理,因此成功的 HTML 表格应该增强视力正常和视力障碍用户的体验。

表格样式

您也可以在 GitHub 上 查看实时示例!您会注意到,那里的表格看起来更易读——这是因为您在此页面上看到的表格样式最少,而 GitHub 版本应用了更重要的 CSS。

不要有任何幻想;为了使表格在 Web 上有效,您需要使用 CSS 提供一些样式信息,以及使用 HTML 提供良好的结构。在本模块中,我们重点关注 HTML 部分;要了解 CSS 部分,您应该在完成此操作后访问我们的 样式化表格 文章。

在本模块中,我们不会关注 CSS,但我们为您提供了一个最小的 CSS 样式表,您可以使用它来使表格比没有样式的默认样式更易读。您可以在此处找到 样式表,还可以找到一个 HTML 模板,该模板应用了样式表——这些结合在一起将为您提供一个良好的起点,用于试验 HTML 表格。

何时不应使用 HTML 表格?

HTML 表格应该用于表格数据——这是它们的设计目的。不幸的是,很多人过去常常使用 HTML 表格来布局网页,例如一行包含标题,一行包含内容列,一行包含页脚,等等。您可以在我们的 无障碍学习模块 中的 页面布局 中找到更多详细信息和示例。这之所以常用,是因为浏览器之间的 CSS 支持过去很糟糕;如今,表格布局不那么常见了,但您仍然可能会在 Web 的某些角落看到它们。

简而言之,将表格用于布局而不是 CSS 布局技术 是一个坏主意。主要原因如下

  1. 布局表格会降低视障用户的可访问性屏幕阅读器,由盲人使用,会解读 HTML 页面中的标签并将其内容读给用户听。由于表格并非用于布局的正确工具,并且其标记比 CSS 布局技术更复杂,因此屏幕阅读器的输出对用户来说会令人困惑。
  2. 表格会产生标签汤:如上所述,表格布局通常涉及比正确布局技术更复杂的标记结构。这可能导致代码更难编写、维护和调试。
  3. 表格并非自动响应式:当您使用正确的布局容器(例如 <header><section><article><div>)时,它们的宽度默认为其父元素的 100%。另一方面,表格默认情况下会根据其内容进行大小调整,因此需要采取额外措施才能使表格布局样式在各种设备上有效地工作。

主动学习:创建您的第一个表格

我们已经讨论了足够的表格理论,所以让我们深入了解一个实际的例子并构建一个简单的表格。

  1. 首先,在您本地计算机上的新目录中创建 blank-template.htmlminimal-table.css 的本地副本。
  2. 每个表格的内容都包含在这两个标签之间:<table></table>。将它们添加到 HTML 的 body 中。
  3. 表格中最小的容器是表格单元格,它由 <td> 元素创建('td' 代表 'table data')。将以下内容添加到您的表格标签内
    html
    <td>Hi, I'm your first cell.</td>
    
  4. 如果我们想要一行四个单元格,我们需要将这些标签复制三次。更新表格的内容使其如下所示
    html
    <td>Hi, I'm your first cell.</td>
    <td>I'm your second cell.</td>
    <td>I'm your third cell.</td>
    <td>I'm your fourth cell.</td>
    

您会看到,这些单元格不是彼此上下放置的,而是自动在同一行上彼此对齐。每个 <td> 元素创建一个单元格,它们共同构成第一行。我们添加的每个单元格都会使该行变长。

为了停止该行的增长并开始在第二行上放置后续单元格,我们需要使用 <tr> 元素('tr' 代表 'table row')。现在让我们来研究一下。

  1. 将您已创建的四个单元格放在 <tr> 标签内,如下所示
    html
    <tr>
      <td>Hi, I'm your first cell.</td>
      <td>I'm your second cell.</td>
      <td>I'm your third cell.</td>
      <td>I'm your fourth cell.</td>
    </tr>
    
  2. 现在您已经创建了一行,尝试再创建一两行——每一行都需要用一个额外的 <tr> 元素进行包装,每个单元格都包含在 <td> 中。

结果

这应该会生成一个看起来类似于以下内容的表格

注意:您也可以在 GitHub 上找到它,网址为 simple-table.html也可以在线查看)。

使用 <th> 元素添加标题

现在让我们将注意力转向表格标题——位于行或列开头并定义该行或列包含的数据类型的特殊单元格(例如,请参阅本文开头显示的第一个示例中的“Person”和“Age”单元格)。为了说明它们为何有用,请查看以下表格示例。首先是源代码

html
<table>
  <tr>
    <td>&nbsp;</td>
    <td>Knocky</td>
    <td>Flor</td>
    <td>Ella</td>
    <td>Juan</td>
  </tr>
  <tr>
    <td>Breed</td>
    <td>Jack Russell</td>
    <td>Poodle</td>
    <td>Streetdog</td>
    <td>Cocker Spaniel</td>
  </tr>
  <tr>
    <td>Age</td>
    <td>16</td>
    <td>9</td>
    <td>10</td>
    <td>5</td>
  </tr>
  <tr>
    <td>Owner</td>
    <td>Mother-in-law</td>
    <td>Me</td>
    <td>Me</td>
    <td>Sister-in-law</td>
  </tr>
  <tr>
    <td>Eating Habits</td>
    <td>Eats everyone's leftovers</td>
    <td>Nibbles at food</td>
    <td>Hearty eater</td>
    <td>Will eat till he explodes</td>
  </tr>
</table>

现在是实际渲染的表格

这里的问题是,虽然您可以大致了解发生了什么,但与可能的情况相比,交叉引用数据并不容易。如果列和行标题以某种方式突出显示,效果会好得多。

主动学习:表格标题

让我们尝试改进此表格。

  1. 首先,在您本地计算机上的新目录中创建我们的 dogs-table.htmlminimal-table.css 文件的本地副本。HTML 包含与上面您看到的相同的 Dogs 示例。
  2. 为了在视觉上和语义上将表格标题识别为标题,您可以使用 <th> 元素('th' 代表 'table header')。它的工作方式与 <td> 完全相同,只是它表示标题,而不是普通单元格。进入您的 HTML,并将围绕表格标题的所有 <td> 元素更改为 <th> 元素。
  3. 保存您的 HTML 并将其加载到浏览器中,您应该会看到标题现在看起来像标题了。

注意:您可以在 GitHub 上找到我们的完成示例,网址为 dogs-table-fixed.html也可以在线查看)。

标题为何有用?

我们已经部分回答了这个问题——当标题清晰突出显示时,更容易找到您要查找的数据,并且设计总体上看起来更好。

注意:表格标题具有一些默认样式——即使您没有向表格添加自己的样式,它们也会加粗并居中,以帮助它们脱颖而出。

表格标题还有一个额外的好处——与 scope 属性(我们将在下一篇文章中学习)一起,它们使您可以通过将每个标题与同一行或列中的所有数据相关联来提高表格的可访问性。然后,屏幕阅读器能够一次读出一整行或一列数据,这非常有用。

允许单元格跨越多行和多列

有时我们希望单元格跨越多行或多列。请以以下简单示例为例,该示例显示了常见动物的名称。在某些情况下,我们希望将雄性和雌性的名称显示在动物名称旁边。有时我们不希望这样做,在这种情况下,我们只希望动物名称跨越整个表格。

初始标记如下所示

html
<table>
  <tr>
    <th>Animals</th>
  </tr>
  <tr>
    <th>Hippopotamus</th>
  </tr>
  <tr>
    <th>Horse</th>
    <td>Mare</td>
  </tr>
  <tr>
    <td>Stallion</td>
  </tr>
  <tr>
    <th>Crocodile</th>
  </tr>
  <tr>
    <th>Chicken</th>
    <td>Hen</td>
  </tr>
  <tr>
    <td>Rooster</td>
  </tr>
</table>

但输出结果并非我们想要的结果

我们需要一种方法来使“Animals”、“Hippopotamus”和“Crocodile”跨越两列,“Horse”和“Chicken”向下跨越两行。幸运的是,表格标题和单元格具有 colspanrowspan 属性,它们使我们能够做到这一点。两者都接受一个无单位的数值,该值等于您想要跨越的行数或列数。例如,colspan="2" 使单元格跨越两列。

让我们使用 colspanrowspan 来改进此表格。

  1. 首先,在您本地计算机上的新目录中创建我们的 animals-table.htmlminimal-table.css 文件的本地副本。HTML 包含与上面您看到的相同的动物示例。
  2. 接下来,使用 colspan 使“Animals”、“Hippopotamus”和“Crocodile”跨越两列。
  3. 最后,使用 rowspan 使“Horse”和“Chicken”跨越两行。
  4. 保存并在浏览器中打开您的代码以查看改进效果。

注意:您可以在 GitHub 上找到我们的完成示例,网址为 animals-table-fixed.html也可以在线查看)。

为列提供通用样式

不使用 <col> 进行样式设置

在继续之前,本文中还有一项功能需要告诉您。HTML 有一种方法可以定义一整列数据的样式信息,只需在一个地方即可——<col><colgroup> 元素。它们的存在是因为为列指定样式信息可能有点烦人和低效——您通常必须在该列中的每个 <td><th> 上指定样式信息,或者使用复杂的类似于 :nth-child 的选择器。

注意:这种样式列的方法仅限于少数属性borderbackgroundwidthvisibility。要设置其他属性,您必须为该列中的每个 <td><th> 设置样式,或者使用复杂的类似于 :nth-child 的选择器。

请以以下简单示例为例

html
<table>
  <tr>
    <th>Data 1</th>
    <th style="background-color: yellow">Data 2</th>
  </tr>
  <tr>
    <td>Calcutta</td>
    <td style="background-color: yellow">Orange</td>
  </tr>
  <tr>
    <td>Robots</td>
    <td style="background-color: yellow">Jazz</td>
  </tr>
</table>

这将给我们以下结果

这不是理想的,因为我们必须在该列中的所有三个单元格上重复样式信息(在实际项目中,我们可能会在所有三个单元格上设置一个 class 并在一个单独的样式表中指定样式)。

使用 <col> 进行样式设置

与其这样做,我们可以对 <col> 元素指定一次信息。<col> 元素在 <colgroup> 容器内指定,该容器位于 <table> 开头标签的下方。我们可以通过如下方式指定表格来创建与上面看到的相同的效果

html
<table>
  <colgroup>
    <col />
    <col style="background-color: yellow" />
  </colgroup>
  <tr>
    <th>Data 1</th>
    <th>Data 2</th>
  </tr>
  <tr>
    <td>Calcutta</td>
    <td>Orange</td>
  </tr>
  <tr>
    <td>Robots</td>
    <td>Jazz</td>
  </tr>
</table>

实际上,我们定义了两个“样式列”,一个为每一列指定样式信息。我们没有为第一列设置样式,但我们仍然必须包含一个空的 <col> 元素——如果我们不这样做,样式将只应用于第一列。

如果我们想将样式信息应用于两列,我们只需包含一个带有 span 属性的 <col> 元素,如下所示

html
<colgroup>
  <col style="background-color: yellow" span="2" />
</colgroup>

colspanrowspan 一样,span 接受一个无单位的数值,该值指定您希望样式应用到的列数。

注意:当表格、列和该列中的表格单元格都分别设置样式时,应用于单元格的样式将绘制在列样式之上,而列样式将绘制在表格之上。这是因为表格层首先渲染,然后是列层渲染,单元格层渲染在所有其他表格层之上

主动学习:colgroup 和 col

现在轮到您自己动手了。

下面您可以看到一位语言教师的时间表。周五,她有一节新的荷兰语课程,整天都在上课,但周二和周四,她也会教授几节德语课程。她想突出显示她正在教授课程的日期所在的列。

按照以下步骤重新创建表格。

  1. 首先,在您本地计算机上的新目录中创建我们的 timetable.html 文件的本地副本。HTML 包含与上面您看到的相同的表格,但缺少列样式信息。
  2. 在表格顶部,紧靠 <table> 标签下方,添加一个 <colgroup> 元素,您可以在其中添加 <col> 元素(请参阅以下剩余步骤)。
  3. 前两列需要保持不设置样式。
  4. 向第三列添加背景颜色。style 属性的值为 background-color:#97DB9A;
  5. 为第四列设置单独的宽度。style 属性的值为 width: 100px;
  6. 向第五列添加背景颜色。style 属性的值为 background-color: #97DB9A;
  7. 向第六列添加不同的背景颜色和边框,以表示这是一个特殊的日子,并且她正在教授新课程。style 属性的值为 background-color:#DCC48E; border:4px solid #C1437A;
  8. 最后两天是休息日,因此只需将它们设置为无背景颜色,但设置宽度;style 属性的值为 width: 100px;

看看您对示例的处理情况。如果您遇到问题或想检查您的工作,您可以在 GitHub 上找到我们的版本,网址为 timetable-fixed.html也可以在线查看)。

总结

这几乎涵盖了 HTML 表格的基础知识。在下一篇文章中,我们将了解一些更高级的表格功能,并开始思考它们对于视障人士的可访问性。