rowspan必须写在跨行区域最上方单元格的<td>或<th>中,且后续被跨行的行须跳过对应列的<td>;值须为正整数,与colspan混用时需确保每行等效列数一致。

rowspan必须写在起始单元格的<td>里
跨行合并不是“选中多行再点合并”,而是由某个单元格主动声明:“我往下占N行”。这个声明只能写在**它自己所在的<td>或<th>标签里**,且必须是该跨行区域最上方那个单元格。
常见错误是把rowspan="2"写在第二行的<td>里——此时第一行该列已被占满,浏览器直接忽略,视觉上毫无变化。
- 正确:
<tr><td rowspan="2">姓名</td><td>张三</td></tr> - 错误:
<tr><td>姓名</td><td>张三</td></tr><tr><td rowspan="2">李四</td><td>数学</td></tr>(第一行已占位,第二行再设无效)
被跨过的行必须跳过对应列的<td>
rowspan不会自动“删除”下面的单元格,它只是告诉浏览器:“这一列位置我占了,你别再画”。如果后续行还照常写<td>,就会多出一列,导致整行错位、内容重叠或列头对不齐。
比如第一行<td rowspan="3">A</td><td>B1</td>,那么第二、三行的<tr>里**不能出现左列的<td>**,只保留右列内容:
立即学习“前端免费学习笔记(深入)”;
<table border="1"> <tr><td rowspan="3">A</td><td>B1</td></tr> <tr><td>B2</td></tr> <tr><td>B3</td></tr> </table>
- 漏掉跳过 → 表格列数计算错误,
document.querySelector('tr:nth-child(2) td:nth-child(1)')可能选到错误元素 - 用开发者工具检查每个
<tr>下实际渲染的<td>数量,比肉眼数 HTML 更可靠
rowspan值必须是正整数,不能为0或字符串
rowspan="0"在规范里无效,Chrome、Firefox 都会当rowspan="1"处理;rowspan="2.5"或rowspan="two"会被忽略。动态生成时尤其要注意:
- JS 中计算出的值必须是数字类型,不要用
String(num)包装后塞进属性 - 避免逻辑漏洞导致
rowspan="-1"或rowspan="0",这类值浏览器不报错但语义断裂 - 超出行数限制(如
rowspan="99"但只剩2行)时,浏览器按剩余行数渲染,但table.rows[i].cells.length等 DOM 属性可能返回意外结果
和colspan混用时,列总数必须对得上
一个<td rowspan="2" colspan="3">会同时占 2 行 × 3 列 = 6 个原始格子。这意味着:它所在行要少写 2 个<td>(因为右侧两列被吞),接下来一行也要少写 2 个<td>(因为同一列位置被跨占)。
最容易翻车的是:某行<tr>中<td>个数与其他行不一致,又没意识到rowspan/colspan已改变实际列宽。结果就是表头偏移、CSS :nth-child() 失效、响应式断点错乱。
- 验证技巧:
Array.from(tr.children).reduce((sum, td) => sum + (td.colSpan || 1), 0)计算每行“等效列数”,确保全部相等 - 复杂合并建议先手绘 3×3 或 4×4 网格,标出每个单元格的
rowspan/colspan值再写代码
<td>,取决于前面所有rowspan的累计占用——这里漏一次跳过,后面整张表就偏了。



















