colspan:一个单元格横跨多列
colspan="n" 让单元格的宽度等于 n 列。它所在的行因此少写 n - 1 个单元格。下面的合计横跨前两列:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>colspan</title>
<style>
table { border-collapse: collapse; font-family: system-ui, sans-serif; }
th, td { border: 1px solid #6b7280; padding: 6px 12px; }
.span { background: #dbeafe; }
</style>
</head>
<body>
<table>
<tr><th>Item</th><th>Qty</th><th>Price</th></tr>
<tr><td>Pens</td><td>2</td><td>4.00</td></tr>
<tr><td>Paper</td><td>1</td><td>6.50</td></tr>
<tr><td class="span" colspan="2">Total</td><td>10.50</td></tr>
</table>
</body>
</html>
最后一行只有两个单元格,但第一个算作两个,所以这一行和其他行一样,加起来还是三列。
rowspan:一个单元格向下跨越多行
rowspan="n" 让单元格的高度等于 n 行。它下面的行要省略这一列,因为这个高单元格已经填满了它:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>rowspan</title>
<style>
table { border-collapse: collapse; font-family: system-ui, sans-serif; }
th, td { border: 1px solid #6b7280; padding: 6px 12px; }
.span { background: #dcfce7; }
</style>
</head>
<body>
<table>
<tr><th>Team</th><th>Member</th></tr>
<tr><td class="span" rowspan="3">Design</td><td>Ana</td></tr>
<tr><td>Bob</td></tr>
<tr><td>Cy</td></tr>
<tr><td>Web</td><td>Dee</td></tr>
</table>
</body>
</html>
Bob 和 Cy 这两行只有一个 <td>:Team 列已经被 “Design” 占了。HTML 里不会标出这一点,所以读带 rowspan 的表格时要从上往下读,并记住哪些列仍被覆盖。
colspan 和 rowspan 一起用:课程表
一个单元格可以同时向两个方向合并。课程表就是典型例子:有的课持续两个时段,有的课跨越两天:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Timetable</title>
<style>
table { border-collapse: collapse; font-family: system-ui, sans-serif; text-align: center; }
th, td { border: 1px solid #6b7280; padding: 8px 14px; }
thead th { background: #e5e7eb; }
.html { background: #fde68a; }
.css { background: #bfdbfe; }
.lab { background: #bbf7d0; }
</style>
</head>
<body>
<table>
<thead>
<tr><th scope="col">Time</th><th scope="col">Mon</th><th scope="col">Tue</th><th scope="col">Wed</th></tr>
</thead>
<tbody>
<tr><th scope="row">9:00</th><td class="html" rowspan="2">HTML</td><td class="css">CSS</td><td>Free</td></tr>
<tr><th scope="row">10:00</th><td class="lab" colspan="2" rowspan="2">Lab</td></tr>
<tr><th scope="row">11:00</th><td>Free</td></tr>
</tbody>
</table>
</body>
</html>
数一数 10:00 这一行:先是时间表头,然后 Mon 被上一行的 HTML 覆盖,接着 Lab 填满 Tue 和 Wed。到了 11:00,Mon 又空出来了,而 Lab 仍覆盖 Tue 和 Wed,所以这一行只有一个数据单元格。
数清单元格,让表格保持整齐
算上每个单元格的 colspan,以及上方 rowspan 单元格覆盖的列,每一行加起来的列数都必须相同。如果某一行多了一个单元格,浏览器会为它新增一列,表格边缘就会参差不齐:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Wrong count</title>
<style>
body { display: flex; flex-wrap: wrap; gap: 24px; font-family: system-ui, sans-serif; }
table { border-collapse: collapse; }
th, td { border: 1px solid #6b7280; padding: 6px 12px; }
.span { background: #dcfce7; }
.extra { background: #fee2e2; }
</style>
</head>
<body>
<table>
<caption>Wrong</caption>
<tr><td class="span" rowspan="2">A</td><td>B</td></tr>
<tr><td>C</td><td class="extra">D</td></tr>
</table>
<table>
<caption>Right</caption>
<tr><td class="span" rowspan="2">A</td><td>B</td></tr>
<tr><td>C</td></tr>
</table>
</body>
</html>
在错误的表格里,第二行忘了 A 已经覆盖了它的第一列,于是 D 落到了其他行都没有的第三列。修复方法是删掉一个单元格。用 colspan 时也会犯同样的错:带宽单元格的那一行保留了原来全部的单元格。
少一个单元格则是相反的问题:这一行提前结束,末尾留下一个空洞。
用 colspan 制作分组表头
表头可以横跨它所标注的那几列,放在一行更具体的表头上方。给它加上 scope="colgroup",屏幕阅读器就会把它应用到下面的所有列:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Grouped headers</title>
<style>
table { border-collapse: collapse; font-family: system-ui, sans-serif; }
th, td { border: 1px solid #6b7280; padding: 6px 12px; text-align: center; }
thead th { background: #e5e7eb; }
</style>
</head>
<body>
<table>
<colgroup><col></colgroup>
<colgroup span="2"></colgroup>
<colgroup span="2"></colgroup>
<thead>
<tr>
<th rowspan="2" scope="col">City</th>
<th colspan="2" scope="colgroup">January</th>
<th colspan="2" scope="colgroup">July</th>
</tr>
<tr>
<th scope="col">Low</th><th scope="col">High</th>
<th scope="col">Low</th><th scope="col">High</th>
</tr>
</thead>
<tbody>
<tr><th scope="row">Oslo</th><td>-7</td><td>-1</td><td>13</td><td>22</td></tr>
<tr><th scope="row">Rome</th><td>3</td><td>12</td><td>19</td><td>31</td></tr>
</tbody>
</table>
</body>
</html>
“City” 用 rowspan="2" 跨越两行表头,每个月份用 colspan="2" 跨越自己的两列。<colgroup> 元素定义了 scope="colgroup" 所指的列组。这样,屏幕阅读器读到 Rome 的 31 单元格时,就能读出 “Rome, July, High, 31”。表格结构的其他部分,参见 HTML 表格。
只在结构真正需要时合并
合并单元格会让表格更难用屏幕阅读器阅读,也更难排序、筛选或复制到电子表格里。只在数据确实分组时使用它们(合计、子列上方的表头、持续两小时的课)。如果一个表格需要很多合并,拆成两个更简单的表格通常更清楚。
常见错误
- 保留了被覆盖的单元格。 一个
colspan="2" 的单元格代替两个单元格;删掉原来的一个。
- 忘了
rowspan 下方的行。 其中每一行都要少一个单元格。
- 把
colspan 写在 <tr> 上。 它只对 <td> 和 <th> 有效。
- 为了视觉布局而合并,比如在页面布局表格中放一行横幅。布局请用 CSS grid。
- 用
colspan="100%" 表示“占满整个宽度”。浏览器只读取开头的数字,所以这个单元格会跨越 100 列,并给表格添加空列。这个值是整数列数。