合并单元格(rowspan / colspan)
rowspan 和 colspan 属性可以让单元格跨越多行或多列。本节将介绍这两个属性的正确用法、常见错误以及合并单元格时的注意事项。
前置知识
阅读本节前,建议先了解:thead / tbody / tfoot
基础概念
colspan 让一个单元格水平跨越多列,rowspan 让一个单元格垂直跨越多行。合并单元格是表格布局中最容易出错的特性之一——需要正确计算被"占据"的单元格,确保行和列的单元格总数正确。
语法
colspan 跨列合并
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>colspan</title>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 10px; text-align: center; }
th { background: #4285f4; color: #fff; }
</style>
</head>
<body>
<h1>colspan 跨列合并</h1>
<table>
<thead>
<tr>
<th colspan="3">2024 年度报告</th>
<!-- 此 th 占据 3 列 -->
</tr>
<tr>
<th>月份</th>
<th>收入</th>
<th>支出</th>
</tr>
</thead>
<tbody>
<tr>
<td>1 月</td>
<td>50,000</td>
<td>35,000</td>
</tr>
<tr>
<td>2 月</td>
<td>55,000</td>
<td>38,000</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">总收入</td>
<!-- 占据 2 列 -->
<td>105,000</td>
</tr>
</tfoot>
</table>
</body>
</html>rowspan 跨行合并
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>rowspan</title>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 10px; text-align: center; }
th { background: #34a853; color: #fff; }
</style>
</head>
<body>
<h1>rowspan 跨行合并</h1>
<table>
<thead>
<tr>
<th>地区</th>
<th>城市</th>
<th>人口</th>
</tr>
</thead>
<tbody>
<tr>
<!-- 此 td 跨越 3 行 -->
<td rowspan="3" style="font-weight: bold;">华北</td>
<td>北京</td>
<td>2189 万</td>
</tr>
<tr>
<!-- 不需要华北的 td,已被上方占据 -->
<td>天津</td>
<td>1387 万</td>
</tr>
<tr>
<td>石家庄</td>
<td>1103 万</td>
</tr>
<tr>
<td rowspan="2" style="font-weight: bold;">华东</td>
<td>上海</td>
<td>2487 万</td>
</tr>
<tr>
<td>杭州</td>
<td>1237 万</td>
</tr>
</tbody>
</table>
</body>
</html>详细说明
colspan 与 rowspan 的值
| 属性 | 值 | 说明 |
|---|---|---|
colspan | 正整数(默认 1) | 跨越的列数 |
rowspan | 正整数(默认 1) | 跨越的行数 |
colspan="0" | 跨越剩余所有列 | 仅在 <colgroup> 中 |
rowspan 的常见错误
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>rowspan 错误</title>
<style>
table { border-collapse: collapse; }
th, td { border: 1px solid #ddd; padding: 10px; text-align: center; }
</style>
</head>
<body>
<h1>rowspan 的注意事项</h1>
<!--
rowspan=2 表示此单元格占据当前行和下一行
下一行中不需要再写对应的 td
-->
<!-- 正确写法 -->
<table border="1">
<tr>
<th rowspan="2">类别</th>
<th>项目 A</th>
<th>项目 B</th>
</tr>
<tr>
<!-- 不需要"类别"的 td -->
<td>100</td>
<td>200</td>
</tr>
</table>
<hr>
<!-- 错误写法! -->
<!--
<table border="1">
<tr>
<th rowspan="2">类别</th>
<th>项目 A</th>
<th>项目 B</th>
</tr>
<tr>
<th>类别</th> <-- 错误!rowspan 已经占据了这个位置
<td>100</td>
<td>200</td>
</tr>
</table>
-->
</body>
</html>rowspan 常见陷阱
使用 rowspan 时,被跨越的行中不要再写对应的 <td> 或 <th>。多写一个单元格会导致整行多出一列,破坏表格布局。
同时使用 rowspan 和 colspan
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>同时合并</title>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 10px; text-align: center; }
th { background: #f5f5f5; }
</style>
</head>
<body>
<h1>同时使用 rowspan 和 colspan</h1>
<table>
<thead>
<tr>
<th>部门</th>
<th colspan="2">人数</th>
<th colspan="2">薪资(万元)</th>
</tr>
<tr>
<th></th>
<th>男</th>
<th>女</th>
<th>男均</th>
<th>女均</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2">技术部</td>
<td>15</td>
<td>8</td>
<td>25</td>
<td>22</td>
</tr>
<tr>
<!-- 技术部的 td 被 rowspan 占据 -->
<td colspan="3">合计:23 人</td>
<td>23.7</td>
</tr>
</tbody>
</table>
</body>
</html>实战示例
课程表
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; }
th, td { padding: 10px; text-align: center; border: 1px solid #ddd; }
th { background: #4285f4; color: #fff; }
td.time { background: #f5f5f5; font-weight: bold; text-align: left; }
td.break { background: #fff3e0; }
caption {
caption-side: top;
font-size: 18px;
font-weight: bold;
padding: 12px 0;
text-align: center;
}
</style>
</head>
<body>
<table>
<caption>2024 年秋季课程表</caption>
<thead>
<tr>
<th>时间</th>
<th>周一</th>
<th>周二</th>
<th>周三</th>
<th>周四</th>
<th>周五</th>
</tr>
</thead>
<tbody>
<tr>
<td class="time" rowspan="2">上午 1-2 节</td>
<td>数学</td>
<td>英语</td>
<td>物理</td>
<td>语文</td>
<td>化学</td>
</tr>
<tr>
<td>数学</td>
<td>英语</td>
<td>物理</td>
<td>语文</td>
<td>化学</td>
</tr>
<tr>
<td class="time" rowspan="2">上午 3-4 节</td>
<td>语文</td>
<td>物理</td>
<td>英语</td>
<td>生物</td>
<td>历史</td>
</tr>
<tr>
<td>语文</td>
<td>物理</td>
<td>英语</td>
<td>生物</td>
<td>历史</td>
</tr>
<tr>
<td class="time">午休</td>
<td colspan="5" class="break">12:00 - 14:00</td>
</tr>
<tr>
<td class="time" rowspan="2">下午 5-6 节</td>
<td>体育</td>
<td>音乐</td>
<td>美术</td>
<td>信息</td>
<td>班会</td>
</tr>
<tr>
<td>体育</td>
<td>音乐</td>
<td>美术</td>
<td>信息</td>
<td>班会</td>
</tr>
</tbody>
</table>
</body>
</html>注意事项
- 使用
rowspan时,被跨越的行中省略对应的<td> - 使用
colspan时,该行中减少对应数量的<td> - 不要让
rowspan/colspan跨越<thead>/<tbody>/<tfoot>的边界 - 复杂的合并单元格在移动端可能难以阅读
- 避免过度使用合并单元格,保持表格结构清晰
最佳实践
- 仅在确实需要时才使用合并单元格
- 保持合并逻辑简单明了
- 使用注释标明被跨越的单元格位置
- 确保每行的实际单元格数(含合并后)一致
- 复杂数据结构考虑使用多张简单表格
下一节
继续学习:scope 与 headers