Skip to content

无障碍表格设计

无障碍表格设计确保所有用户——包括使用屏幕阅读器的视障用户和使用辅助技术的用户——都能正确理解表格数据。本节将介绍表格无障碍的核心原则、已废弃的 summary 属性及其替代方案,以及 ARIA 表格角色。

前置知识

阅读本节前,建议先了解:scope 与 headers

基础概念

表格无障碍设计的核心目标是让辅助技术(如屏幕阅读器)能够正确解读表格的结构和关联关系。一个无障碍的表格需要:清晰的标题、正确的关联关系、有意义的描述文本,以及避免使用表格做布局。

HTML5 中,<table>summary 属性已被废弃,替代方案是使用 <caption> 和 ARIA 属性。

详细说明

summary 属性(已废弃)

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>summary 废弃</title>
</head>
<body>
  <h1>summary 属性(已废弃)</h1>

  <!--
    summary 属性在 HTML5 中已废弃
    它曾经用于为表格提供描述,只有辅助技术能读取
  -->

  <!-- 错误!summary 已废弃 -->
  <!-- <table summary="2024年各部门季度销售额汇总,单位万元"> -->

  <!-- 正确替代方案 1:使用 caption -->
  <table>
    <caption>
      2024 年各部门季度销售额汇总(单位:万元)
    </caption>
    <thead>
      <tr>
        <th>部门</th>
        <th>Q1</th>
        <th>Q2</th>
      </tr>
    </thead>
    <tbody>
      <tr><td>技术部</td><td>120</td><td>150</td></tr>
    </tbody>
  </table>

  <!-- 正确替代方案 2:使用 aria-label -->
  <!-- <table aria-label="2024年各部门季度销售额汇总"> -->
</body>
</html>

caption 替代 summary 的方案

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>caption 替代方案</title>
  <style>
    table { border-collapse: collapse; width: 100%; }
    th, td { border: 1px solid #ddd; padding: 10px; text-align: center; }
    th { background: #4285f4; color: #fff; }
    caption {
      caption-side: top;
      text-align: left;
      padding: 0 0 12px;
    }
    /* 可见的 caption 适合所有用户 */
    .vis-caption {
      font-size: 18px;
      font-weight: bold;
      display: block;
    }
    .vis-caption-desc {
      font-size: 14px;
      color: #666;
      display: block;
      margin-top: 4px;
    }
    /* 不可见的描述:只给屏幕阅读器 */
    .sr-only {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip: rect(0,0,0,0);
    }
  </style>
</head>
<body>
  <h1>caption 替代 summary</h1>

  <!-- 方案 1:所有信息可见 -->
  <table>
    <caption>
      <span class="vis-caption">季度销售数据</span>
      <span class="vis-caption-desc">
        包含三个部门(技术部、市场部、运营部)四个季度的销售数据,
        单位为万元。
      </span>
    </caption>
    <thead>
      <tr>
        <th>部门</th>
        <th>Q1</th>
        <th>Q2</th>
      </tr>
    </thead>
    <tbody>
      <tr><td>技术部</td><td>120</td><td>150</td></tr>
    </tbody>
  </table>

  <!-- 方案 2:caption 简短 + 不可见补充 -->
  <table>
    <caption>季度销售数据</caption>
    <div class="sr-only">
      此表格包含三个部门四个季度的销售数据,单位万元。
      上涨表示比上季度增长,下降表示比上季度减少。
    </div>
    <thead>
      <tr>
        <th>部门</th>
        <th>Q1</th>
        <th>Q2</th>
      </tr>
    </thead>
    <tbody>
      <tr><td>市场部</td><td>80</td><td>95</td></tr>
    </tbody>
  </table>
</body>
</html>

ARIA 表格角色

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>ARIA 表格角色</title>
  <style>
    table { border-collapse: collapse; width: 100%; }
    th, td { border: 1px solid #ddd; padding: 10px; text-align: center; }
  </style>
</head>
<body>
  <h1>ARIA 表格角色</h1>

  <!--
    大部分情况下,HTML5 语义表格不需要 ARIA 角色
    但以下角色可用于增强无障碍:
  -->

  <!-- 数据表格 -->
  <table role="table" aria-label="员工信息表">
    <caption>员工信息表</caption>
    <thead role="rowgroup">
      <tr role="row">
        <th scope="col" role="columnheader">姓名</th>
        <th scope="col" role="columnheader">职位</th>
      </tr>
    </thead>
    <tbody role="rowgroup">
      <tr role="row">
        <td role="cell">张三</td>
        <td role="cell">前端工程师</td>
      </tr>
    </tbody>
  </table>

  <!--
    注意:
    - role="table" 只应在非 <table> 元素上使用
    - 如果使用 <table>,浏览器已经隐式添加了角色
    - 不要滥用 ARIA 角色(首选原生语义)
  -->
</body>
</html>

ARIA 角色参考

ARIA 角色等效 HTML说明
role="table"<table>表格容器
role="row"<tr>表格行
role="columnheader"<th scope="col">列标题
role="rowheader"<th scope="row">行标题
role="cell"<td>数据单元格
role="rowgroup"<thead>/<tbody>/<tfoot>行组
role="grid"交互式表格可排序/选择的表格

ARIA 使用原则

首选原生 HTML 语义。只有在原生 HTML 不足以表达语义时才使用 ARIA。HTML 的 <table><tr><th><td> 已经隐式包含了 ARIA 角色,无需额外添加。

不要用表格做布局

html
<!-- 错误!不要用表格做布局 -->
<!--
<table>
  <tr>
    <td>导航栏</td>
  </tr>
  <tr>
    <td>主内容</td>
  </tr>
</table>
-->

<!-- 正确:使用语义化 HTML -->
<header>
  <nav>导航栏</nav>
</header>
<main>主内容</main>

<!-- 如果必须将布局表格保留为兼容代码,添加 ARIA 角色 -->
<table role="presentation">
  <tr>
    <td>导航栏</td>
  </tr>
</table>

实战示例

无障碍友好的数据表

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>无障碍表格</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      max-width: 800px;
      margin: 0 auto;
      padding: 20px;
    }
    table { width: 100%; border-collapse: collapse; }
    caption {
      caption-side: top;
      text-align: left;
      font-size: 18px;
      font-weight: bold;
      padding-bottom: 8px;
    }
    th, td {
      padding: 12px 14px;
      text-align: left;
      border-bottom: 1px solid #eee;
    }
    th {
      background: #4285f4;
      color: #fff;
      text-align: center;
    }
    tbody tr:hover {
      background: #f8f9fa;
    }
  </style>
</head>
<body>
  <table>
    <!-- 1. caption 提供标题和描述 -->
    <caption>
      2024 年第四季度产品销售统计
    </caption>

    <!-- 2. thead 包裹表头 -->
    <thead>
      <tr>
        <th scope="col">产品名称</th>
        <th scope="col">销量(件)</th>
        <th scope="col">营收(万元)</th>
        <th scope="col">同比增长</th>
      </tr>
    </thead>

    <!-- 3. tbody 包裹数据 -->
    <tbody>
      <tr>
        <td>智能手表 Pro</td>
        <td>12,500</td>
        <td>2,500</td>
        <td>+35%</td>
      </tr>
      <tr>
        <td>无线耳机 Max</td>
        <td>28,000</td>
        <td>2,800</td>
        <td>+22%</td>
      </tr>
      <tr>
        <td>便携音箱 Mini</td>
        <td>8,500</td>
        <td>425</td>
        <td>-5%</td>
      </tr>
    </tbody>

    <!-- 4. tfoot 包裹汇总 -->
    <tfoot>
      <tr>
        <td>合计</td>
        <td>49,000</td>
        <td>5,725</td>
        <td>+18%</td>
      </tr>
    </tfoot>
  </table>

  <!-- 5. 可选:不可见的补充描述 -->
  <div style="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);">
    此表格展示了 2024 年第四季度三款产品的销售数据,
    包括销量、营收和同比增长率。同比增长列中 + 表示增长,- 表示下降。
  </div>
</body>
</html>

注意事项

  • summary 属性已废弃,不要在新代码中使用
  • 优先使用 <caption> 提供表格标题和描述
  • .sr-only 类可以提供仅屏幕阅读器可见的补充信息
  • 不要对原生 <table> 添加 role="table"(重复冗余)
  • 布局表格使用 role="presentation" 隐藏表格语义

最佳实践

  • 每个数据表格都应有 <caption>
  • 表头使用 <th> + scope 属性
  • 复杂表格使用 headers 属性建立关联
  • 提供补充描述帮助理解数据含义
  • 不要使用表格做页面布局
  • 测试表格在屏幕阅读器中的朗读效果

下一节

继续学习:form 基础

参考链接