HTML 表格高级功能和可访问性

在本模块的第二篇文章中,我们将介绍 HTML 表格的一些更高级的功能——例如标题/摘要以及将行分组到表头、表体和表尾部分——以及表格对视力障碍用户的无障碍性。

先决条件 HTML 基础知识(参见 HTML 简介)。
目标 了解更高级的 HTML 表格功能以及表格的无障碍性。

使用 <caption> 为表格添加标题

您可以通过将标题放在 <caption> 元素内,并将该元素嵌套在 <table> 元素内,为表格添加标题。您应该将其放在打开的 <table> 标签的正下方。

html
<table>
  <caption>
    Dinosaurs in the Jurassic period
  </caption></table>

如您从上面的简短示例中推断的那样,标题旨在包含对表格内容的描述。这对于所有希望快速了解表格是否对他们有用的读者来说很有用,因为他们浏览页面时,但对盲人用户尤其如此。与其让屏幕阅读器读出许多单元格的内容只是为了找出表格的内容,不如让用户依赖标题,然后决定是否更详细地阅读表格。

标题放在 <table> 标签的正下方。

注意:summary 属性也可以在 <table> 元素上使用以提供描述——这也会被屏幕阅读器读出。但是,我们建议使用 <caption> 元素,因为 summary 已弃用,并且视力正常的用户无法阅读(它不会出现在页面上)。

主动学习:添加标题

让我们尝试一下,重新审视我们在上一篇文章中首次遇到的示例。

  1. 打开您语言老师的学校时间表,该时间表来自 HTML 表格基础 的末尾,或创建我们 timetable-fixed.html 文件的本地副本。
  2. 为表格添加一个合适的标题。
  3. 保存您的代码并在浏览器中打开它,以查看它的外观。

注意:您可以在 GitHub 上找到我们的版本——参见 timetable-caption.html (也查看它)。

使用 <thead>、<tbody> 和 <tfoot> 添加结构

随着表格在结构上变得更加复杂,使用 <thead><tbody><tfoot> 为其提供更多结构定义非常有用,这些元素允许您标记表格的表头、表体和表尾部分。

这些元素不会使表格对屏幕阅读器用户更易访问,也不会独立地导致任何视觉增强。但是,它们对样式和布局非常有用——充当添加 CSS 到表格的有用钩子。为了给您一些有趣的示例,对于长表格,您可以使表格的表头和表尾在每页打印时重复,并且您可以使表格主体显示在一页上,并且内容可通过上下滚动访问。

要使用它们,应按以下顺序包含它们

  • <thead> 元素必须包含表格的表头部分——这通常是包含列标题的第一行,但这并不总是这样。如果您使用的是 <col>/<colgroup> 元素,则表格标题应放在这些元素的正下方。
  • <tbody> 元素需要包含表格内容的主体部分,而不是表格的表头或表尾。
  • <tfoot> 元素需要包含表格的表尾部分——这可能是一行,其中包含前几行中项目的总和,例如。

注意:<tbody> 始终包含在每个表格中,如果您没有在代码中指定,则隐式包含。要检查这一点,请打开您以前不包含 <tbody> 的示例之一,并在您的 浏览器开发工具 中查看 HTML 代码——您将看到浏览器已为您添加了此标签。您可能会想知道为什么您应该费心包含它——您应该这样做,因为它让您对表格结构和样式有更多控制。

主动学习:添加表格结构

让我们将这些新元素付诸行动。

  1. 首先,创建一个 spending-record.htmlminimal-table.css 的本地副本到一个新文件夹中。
  2. 尝试在浏览器中打开它——您会看到它看起来还可以,但可以改进。包含已支出金额总和的“SUM”行似乎位置不对,代码中还有一些细节缺失。
  3. 将明显的标题行放在 <thead> 元素中,“SUM”行放在 <tfoot> 元素中,其余内容放在 <tbody> 元素中。
  4. 保存并刷新,您将看到添加 <tfoot> 元素已导致“SUM”行向下移到表格底部。
  5. 接下来,添加一个 colspan 属性,使“SUM”单元格跨越前四列,以便实际数字出现在“Cost”列的底部。
  6. 让我们为表格添加一些简单的额外样式,以便您了解这些元素对应用 CSS 的作用有多大。在 HTML 文档的头部,您将看到一个空的 <style> 元素。在该元素内,添加以下几行 CSS 代码
    css
    tbody {
      font-size: 95%;
      font-style: italic;
    }
    
    tfoot {
      font-weight: bold;
    }
    
  7. 保存并刷新,看看结果。如果没有 <tbody><tfoot> 元素,您将不得不编写更复杂的选择器/规则才能应用相同的样式。

注意:我们不希望您现在完全理解 CSS。您将在学习 CSS 模块时了解更多有关 CSS 的信息 (CSS 简介 是一个不错的起点;我们还有一篇专门介绍 表格样式 的文章)。

完成后的表格应该看起来像这样

注意:您也可以在 GitHub 上找到它,名称为 spending-record-finished.html

嵌套表格

只要您包含完整的结构,包括 <table> 元素,就可以将一个表格嵌套在另一个表格中。这通常并不建议这样做,因为它会使标记更令人困惑,并且对屏幕阅读器用户更难以访问,并且在许多情况下,您也可以简单地在现有表格中插入额外的单元格/行/列。但是,有时这是必要的,例如,如果您想轻松地从其他来源导入内容。

以下标记显示了一个简单的嵌套表格

html
<table id="table1">
  <tr>
    <th>title1</th>
    <th>title2</th>
    <th>title3</th>
  </tr>
  <tr>
    <td id="nested">
      <table id="table2">
        <tr>
          <td>cell1</td>
          <td>cell2</td>
          <td>cell3</td>
        </tr>
      </table>
    </td>
    <td>cell2</td>
    <td>cell3</td>
  </tr>
  <tr>
    <td>cell4</td>
    <td>cell5</td>
    <td>cell6</td>
  </tr>
</table>

其输出看起来像这样

面向视障用户的表格

让我们简要回顾一下我们如何使用数据表格。表格是一个方便的工具,可以让我们快速访问数据,并让我们查找不同的值。例如,只需快速浏览下面的表格,就可以找到 2016 年 8 月在根特销售了多少枚戒指。为了理解它的信息,我们在这个表格中的数据与其列和/或行标题之间建立了视觉联系。

2016 年 8 月销售的商品
衣服 配饰
裤子 裙子 连衣裙 手镯 戒指
比利时 安特卫普 56 22 43 72 23
根特 46 18 50 61 15
布鲁塞尔 51 27 38 69 28
荷兰 阿姆斯特丹 89 34 69 85 38
乌特勒支 80 12 43 36 19

但是,如果您无法建立这些视觉联系呢?那么您如何阅读上面的表格呢?视力障碍者通常使用屏幕阅读器,屏幕阅读器会向他们朗读网页上的信息。当您阅读纯文本时,这没问题,但解释表格对盲人来说可能是一个不小的挑战。然而,通过适当的标记,我们可以用编程的联系来代替视觉的联系。

注意:根据 2017 年 WHO 数据,大约有 2.53 亿人患有视力障碍。

本文的这一部分提供了使表格尽可能无障碍的其他技术。

使用列标题和行标题

屏幕阅读器将识别所有标题,并使用它们在这些标题与其相关的单元格之间建立编程的联系。列标题和行标题的组合将识别和解释每个单元格中的数据,以便屏幕阅读器用户可以像视力正常的用户一样解释表格。

我们已经在上一篇文章中介绍了标题——参见 使用 <th> 元素添加标题

scope 属性

本文的一个新主题是 scope 属性,该属性可以添加到 <th> 元素中,以告知屏幕阅读器标题究竟是哪个单元格的标题——例如,它是其所在行的标题,还是列的标题?回顾我们前面提到的支出记录示例,您可以明确地将列标题定义为列标题,如下所示

html
<thead>
  <tr>
    <th scope="col">Purchase</th>
    <th scope="col">Location</th>
    <th scope="col">Date</th>
    <th scope="col">Evaluation</th>
    <th scope="col">Cost (€)</th>
  </tr>
</thead>

并且每行都可以像这样定义标题(如果我们添加了行标题以及列标题)

html
<tr>
  <th scope="row">Haircut</th>
  <td>Hairdresser</td>
  <td>12/09</td>
  <td>Great idea</td>
  <td>30</td>
</tr>

屏幕阅读器将识别像这样结构化的标记,并允许其用户一次读出整列或整行,例如。

scope 还有两个可能的取值——colgrouprowgroup。这些用于位于多个列或行之上的标题。如果您回头看看本文开头部分的“2016 年 8 月销售的商品”表格,您将看到“衣服”单元格位于“裤子”、“裙子”和“连衣裙”单元格的正上方。所有这些单元格都应标记为标题 (<th>),但“衣服”是一个位于顶部的标题,它定义了其他三个子标题。“衣服”因此应获得 scope="colgroup" 属性,而其他则应获得 scope="col" 属性

html
<thead>
  <tr>
    <th colspan="3" scope="colgroup">Clothes</th>
  </tr>
  <tr>
    <th scope="col">Trousers</th>
    <th scope="col">Skirts</th>
    <th scope="col">Dresses</th>
  </tr>
</thead>

相同规则也适用于多个分组行的标题。再次查看“2016 年 8 月销售的商品”表格,这次重点关注带有“阿姆斯特丹”和“乌特勒支”标题 (<th>) 的行。您会注意到,“荷兰”标题(也标记为 <th> 元素)跨越两行,是另外两个子标题的标题。因此,应在此标题单元格上指定 scope="rowgroup",以帮助屏幕阅读器建立正确的关联

html
<tr>
  <th rowspan="2" scope="rowgroup">The Netherlands</th>
  <th scope="row">Amsterdam</th>
  <td>89</td>
  <td>34</td>
  <td>69</td>
</tr>
<tr>
  <th scope="row">Utrecht</th>
  <td>80</td>
  <td>12</td>
  <td>43</td>
</tr>

id 和 headers 属性

使用 idheaders 属性来建立标题和单元格之间的关联,是使用 scope 属性的另一种方法。

headers 属性接受一个无序的、用空格分隔的 字符串 列表,每个字符串对应一个提供数据单元格 (<td> 元素) 或另一个标题单元格 (<th> 元素) 的标题的 <th> 元素的唯一 id

这使您的 HTML 表格对表格中每个单元格的位置有了明确的定义,该位置由每个单元格所属的列和行的标题定义,有点像电子表格。为了使其正常工作,表格确实需要列标题和行标题。

回到我们的“2016 年 8 月销售的商品”示例,我们可以像这样使用 idheaders 属性

  1. 在表格的每个<th>元素中添加一个唯一的id
  2. 在每个充当副标题的<th>元素中添加一个headers属性,例如,具有上方的标题元素。该值是位于顶部的标题的id,它定义了副标题,在本例中,对于列标题是"clothes",对于行标题是"belgium"
  3. 在每个<td>元素中添加headers属性,并添加相关<th>元素的id,以空格分隔的列表形式。你可以像在电子表格中那样进行操作:找到数据单元格,并搜索相应的行和列标题。指定id的顺序无关紧要,但应该保持一致以保持组织。
html
<thead>
  <tr>
    <th id="clothes" colspan="3">Clothes</th>
  </tr>
  <tr>
    <th id="trousers" headers="clothes">Trousers</th>
    <th id="skirts" headers="clothes">Skirts</th>
    <th id="dresses" headers="clothes">Dresses</th>
  </tr>
</thead>
<tbody>
  <tr>
    <th id="belgium" rowspan="3">Belgium</th>
    <th id="antwerp" headers="belgium">Antwerp</th>
    <td headers="antwerp belgium clothes trousers">56</td>
    <td headers="antwerp belgium clothes skirts">22</td>
    <td headers="antwerp belgium clothes dresses">43</td>
  </tr>
</tbody>

注意:这种方法在标题和数据单元格之间创建了非常精确的关联,但它使用了大量的标记,并且没有留下任何错误空间。对于大多数表格,scope方法通常就足够了。

主动学习:玩转作用域和标题

  1. 在最后这个练习中,我们希望您首先在新的目录中创建items-sold.htmlminimal-table.css的本地副本。
  2. 现在尝试添加适当的scope属性,使这个表格更易于访问。
  3. 最后,尝试创建启动文件的另一个副本,这次通过使用idheaders属性创建精确且明确的关联,使表格更易于访问。

注意:你可以查看我们的完成示例进行比较——参见items-sold-scope.html也请查看此页面)和items-sold-headers.html也请查看此页面)。

总结

关于 HTML 中表格,你还可以学习一些其他内容,但目前这些知识就足够了。接下来,你可以通过我们的HTML 表格评估进行自测。玩得开心!

如果你已经开始学习 CSS 并且在评估中取得了不错的成绩,你可以继续学习如何为 HTML 表格添加样式——参见表格样式

如果你想开始学习 CSS,请查看CSS 学习区域