跟着 MDN 学 HTML day_58:(构建行星数据表——HTML表格高级实战指南)

引言

在处理结构化数据时,HTML表格依然是最基础且强大的工具之一。MDN的"构建行星数据表"挑战,是一个绝佳的练习,它不仅能帮你巩固
相关标签的基本用法,更能深入理解表格的语义化结构、无障碍访问设计以及复杂单元格的合并逻辑。本文将逐步拆解这个挑战,从零开始构建一个关于太阳系行星数据的完整表格。我们将严格遵循项目概要的要求,分析每一步的实现细节,并提供清晰的代码示例。

1. 搭建表格的语义化骨架

一个具有良好语义的HTML表格并非只有
标签那么简单。它需要逻辑上的区域划分。在这个挑战中,起点是 blank-template.html,我们的第一个任务是初始化表格,提供一个外部容器,并明确地划分出表头 () 和表体 ()。这个例子中不需要表脚 ()。这种划分不仅让代码结构清晰,也为后续通过CSS进行样式差异化控制提供了基础,更重要的是,它帮助屏幕阅读器等辅助技术理解表格内容的组织方式。

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <title>太阳系行星数据</title>
    <link href="minimal-table.css" rel="stylesheet">
</head>
<body>
<h1>太阳系行星数据</h1>

<p style="text-align:center; font-size:0.8rem; color:#333;">
    太阳系中行星的一些数据。(资料取自<a href="http://nssdc.gsfc.nasa.gov/planetary/factsheet/">NASA 行星数据 - 公制</a>,图片取自<a
        href="https://www.nasa.gov/multimedia/imagegallery/">NASA 照片库</a>。)
</p>
<table>
    <colgroup>
        <col span="2">
        <col style="border: 2px solid black ">
        <col span="10">
    </colgroup>

    <thead>
    <tr>
        <th colspan="2"></th>
        <th scope="col">名字</th>
        <th scope="col">图片</th>
        <th scope="col">质量 (10<sup>24</sup>kg)</th>
        <th scope="col">直径 (km)</th>
        <th scope="col">密度<br>(kg/m<sup>3</sup>)</th>
        <th scope="col">重力<br>(m/s<sup>2</sup>)</th>
        <th scope="col">天长<br>(小时)</th>
        <th scope="col">与太阳距离<br>(10<sup>6</sup>km)</th>
        <th scope="col">平均温度<br>(°C)</th>
        <th scope="col">卫星数量</th>
        <th scope="col">备注</th>
    </tr>
    </thead>
    <tbody>
    <!-- 类地行星 -->
    <tr>
        <th rowspan="4" colspan="2" scope="rowgroup">类地行星</th>
        <td scope="row">水星</td>
        <td><img src="https://roy-tian.github.io/learning-area/html/tables/assessment-finished/images/mercury.jpg"
                 alt="水星" width="40"></td>
        <td>0.330</td>
        <td>4,879</td>
        <td>5427</td>
        <td>3.7</td>
        <td>4222.6</td>
        <td>57.9</td>
        <td>167</td>
        <td>0</td>
        <td>距太阳最近</td>
    </tr>
    <tr>
        <td>金星</td>
        <td><img src="	https://roy-tian.github.io/learning-area/html/tables/assessment-finished/images/venus.jpg"
                 alt="金星" width="40"></td>
        <td>4.87</td>
        <td>12,104</td>
        <td>5243</td>
        <td>8.9</td>
        <td>2802.0</td>
        <td>108.2</td>
        <td>464</td>
        <td>0</td>
        <td></td>
    </tr>
    <tr>
        <td>地球</td>
        <td><img src="https://roy-tian.github.io/learning-area/html/tables/assessment-finished/images/earth.png"
                 alt="地球" width="40"></td>
        <td>5.97</td>
        <td>12,756</td>
        <td>5514</td>
        <td>9.8</td>
        <td>24.0</td>
        <td>149.6</td>
        <td>15</td>
        <td>1</td>
        <td>我们的世界</td>
    </tr>
    <tr>
        <td>火星</td>
        <td><img src="	https://roy-tian.github.io/learning-area/html/tables/assessment-finished/images/mars.jpg"
                 alt="火星" width="40"></td>
        <td>0.642</td>
        <td>6,792</td>
        <td>3933</td>
        <td>3.7</td>
        <td>24.7</td>
        <td>227.9</td>
        <td>-65</td>
        <td>2</td>
        <td>红色星球</td>
    </tr>

    <!-- 类木行星 - 气巨星 -->
    <tr>
        <th rowspan="4">类木行星</th>
        <th rowspan="2">气巨星</th>
        <td>木星</td>
        <td><img src="https://roy-tian.github.io/learning-area/html/tables/assessment-finished/images/jupiter.jpg"
                 alt="木星" width="40"></td>
        <td>1898</td>
        <td>142,984</td>
        <td>1326</td>
        <td>23.1</td>
        <td>9.9</td>
        <td>778.6</td>
        <td>-110</td>
        <td>67</td>
        <td>太阳系最大</td>
    </tr>
    <tr>
        <td>土星</td>
        <td><img src="https://roy-tian.github.io/learning-area/html/tables/assessment-finished/images/jupiter.jpg"
                 alt="土星" width="40"></td>
        <td>568</td>
        <td>120,536</td>
        <td>687</td>
        <td>9.0</td>
        <td>10.7</td>
        <td>1433.5</td>
        <td>-140</td>
        <td>62</td>
        <td></td>
    </tr>

    <!-- 类木行星 - 冰巨星 -->
    <tr>
        <th rowspan="2">冰巨星</th>
        <td>天王星</td>
        <td><img src="	https://roy-tian.github.io/learning-area/html/tables/assessment-finished/images/uranus.jpg"
                 alt="天王星" width="40"></td>
        <td>86.8</td>
        <td>51,118</td>
        <td>1271</td>
        <td>8.7</td>
        <td>17.2</td>
        <td>2872.5</td>
        <td>-195</td>
        <td>27</td>
        <td></td>
    </tr>
    <tr>
        <td>海王星</td>
        <td><img src="https://roy-tian.github.io/learning-area/html/tables/assessment-finished/images/neptune.jpg"
                 alt="海王星" width="40"></td>
        <td>102</td>
        <td>49,528</td>
        <td>1638</td>
        <td>11.0</td>
        <td>16.1</td>
        <td>4495.1</td>
        <td>-200</td>
        <td>14</td>
        <td></td>
    </tr>

    <!-- 矮行星 -->
    <tr>
        <th colspan="2" scope="rowgroup">矮行星</th>
        <td scope="row">冥王星</td>
        <td><img src="https://roy-tian.github.io/learning-area/html/tables/assessment-finished/images/pluto.jpg"
                 alt="冥王星" width="40"></td>
        <td>0.0146</td>
        <td>2,370</td>
        <td>2095</td>
        <td>0.7</td>
        <td>153.3</td>
        <td>5906.4</td>
        <td>-225</td>
        <td>5</td>
        <td>2006年降格,但<a href="http://www.usatoday.com/story/tech/2014/10/02/pluto-planet-solar-system/16578959/">尚存争议</a>。
        </td>
    </tr>
    </tbody>
</table>

</body>
</html>

知识点:scope="rowgroup" 和 scope="row" 的关联艺术

在这个结构中,我们再次看到了 scope 属性的强大之处。对于分组标题如"类地行星",我们设置 scope="rowgroup",这定义了它是一组行的标题。对于每一颗行星的名称,如"水星",我们设置 scope="row",定义它是当前行的标题。这种声明性的关联方式,使得无论表格多么复杂,标题单元格与数据单元格之间的关系都一目了然,无需复杂的ID引用。这正是挑战要点所暗示的更容易的方法。当辅助技术解析这个表格时,它会向用户宣布:"数据单元格:0.330,对应列标题'质量',对应行标题'水星',处于行组'类地行星'之下"。这种层级信息对理解数据至关重要。

4. 视觉样式与语义的最终关联

完成HTML结构后,我们需要添加一些样式来强化视觉呈现,并完成挑战的最后一步。挑战要求"为包含所有行星标题的行标题的那一列数据,添加一个黑色边框"。在 minimal-table.css 文件或内联样式中,我们可以轻松实现这一点。但更重要的是,我们可以利用样式进一步巩固我们通过 scope 属性建立的语义关联。

为了给行星名称那一列添加黑色边框,我们可以直接定位到 scope="row" 的 元素。同时,我们通常也会对表格进行基础的美化,比如添加单元格边框、调整内边距、设置合适的字体等,使表格清晰易读。

css 复制代码
html {
  font-family: sans-serif;
}

table {
  border-collapse: collapse;
  border: 2px solid rgb(200,200,200);
  letter-spacing: 1px;
  font-size: 0.8rem;
}

td, th {
  border: 1px solid rgb(190,190,190);
  padding: 10px 20px;
}

th {
  background-color: rgb(235,235,235);
}

td {
  text-align: center;
}

tr:nth-child(even) td {
  background-color: rgb(250,250,250);
}

tr:nth-child(odd) td {
  background-color: rgb(245,245,245);
}

caption {
  padding: 10px;
}

知识点:CSS属性选择器与表格语义的协同

上面的CSS代码中,最关键的一行是 th[scope="row"] { border-right: 3px solid black; }。这是一个CSS属性选择器的应用,它精确地选中了所有 scope 属性值为 "row" 的 元素。我们在这里完成的不只是一个视觉任务,更是对表格语义结构的视觉强化。一个醒目的黑色竖线清晰地划分了"行标题区域"和"数据区域",这符合数据表格的设计惯例。这种做法的精妙之处在于,我们的CSS不是基于脆弱的类名或ID,也不是基于不稳定的第n个子元素选择器,而是直接和我们为无障碍访问而设置的、稳定的 scope 属性绑定在一起。样式和语义在这里完美统一,一荣俱荣,一损俱损,确保了代码的健壮性和可维护性。

5. 整合与最终审查

将所有片段组合起来,就构成了完整的行星数据表。在最终提交前,我们应该进行一次彻底的审查。检查点包括:

HTML结构是否完整,是否包含了 作为表格的标题。

表头中,colspan 和 rowspan 的计算是否正确,空白单元格是否按要求横跨了2行。

表体中,每一个行星分组标题的 rowspan 值是否与该组内的行星数量一致。

所有行星名称单元格是否都正确地使用了 scope="row" 属性。

CSS中,针对 th[scope="row"] 的样式规则是否生效,黑色边框是否出现在正确的位置。

一个常见的易错点在于对表头中空白单元格合并的理解。我们设置了一个单元格 colspan="2" rowspan="2"。这意味着这个单元格在水平方向占据了2列的空间,在垂直方向占据了2行的空间。因此,在它下方的表头行中,我们不需要再为这两列预留位置,可以直接开始定义后续的6个子列标题。如果你发现表格布局错乱,大概率是 colspan 和 rowspan 的计数与后续行的单元格数量没有匹配上。

最终整合的完整HTML结构示意如下:

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>太阳系行星数据表</title>
    <style>
        /* 此处放置上一节的CSS代码 */
    </style>
</head>
<body>
    <h1>太阳系行星数据</h1>
    <table>
        <caption>太阳系行星数据表,数据来源自MDN学习挑战</caption>
        <thead>
            <!-- 表头代码,同上 -->
        </thead>
        <tbody>
            <!-- 类地行星数据,同上 -->
            <!-- 木星型行星数据,结构类似,rowspan="4" -->
            <!-- 矮行星数据,结构类似,rowspan="2" -->
        </tbody>
    </table>
</body>
</html>

通过这次实践,我们不仅完成了一个漂亮的表格,更重要的是掌握了使用 、、scope、colspan 和 rowspan 等元素和属性来构建语义丰富、结构清晰且无障碍访问的HTML表格这一核心技能。这个挑战完美诠释了如何将杂乱的文本数据,通过结构化的HTML和精准的CSS,转化为一个直观、专业的信息展示界面。


想要解锁更多HTML 核心标签实战、前端零基础入门干货、开发避坑全指南吗?
持续关注,后续将更新CSS 布局实战、JavaScript 交互基础、全站导航开发等硬核内容,带你从新手快速进阶,轻松搞定前端开发!

相关推荐
GDAL1 小时前
Gin c.HTML 完整教程
html·gin
reasonsummer1 小时前
【教学类-160-30】20260513 AI视频培训-练习030“豆包AI视频《春江花月夜》+豆包图片风格:风景
音视频·豆包
kyriewen1 小时前
用户打开飞行模式都能打开你的网站?Service Worker 做离线缓存,PWA 实战
前端·javascript·面试
我是汪先生1 小时前
学习 day8 memory
前端
reasonsummer1 小时前
【教学类-160-34】20260517 AI视频培训-练习034“豆包AI视频《国旗国旗我爱你》(演唱:04ZXY)+豆包图片风格:港风动漫
音视频·豆包图片
BU摆烂会噶1 小时前
【LangGraph】作为节点添加与状态共享
android·人工智能·python·ui·langchain·人机交互
栉甜1 小时前
APIs学习
前端·javascript·css·学习·html
运营小白2 小时前
2026 年 Shopify 关键词映射指南:从混乱到有序的实战经验
前端·一人公司·seonib·自动化内容·搜索流量
Dxy12393102162 小时前
HTML的Iframe详解
前端·html