横向合并单元格本质是用colspan="n"吃掉右侧n−1个单元格,需主动删除被占位的单元格,否则导致列数错乱、边框断裂、对齐失效;每行真实列数必须一致,可用js校验:array.from(tr.children).reduce((s,el)=>s+(el.colspan||1),0)。

横向合并单元格不是“让
colspan 占位后,主动删掉本该存在的其他 <td> ——漏删就会列数错乱、边框断裂、下一行对不齐。
<h3>colspan="n" 的真实含义是“吃掉右边 n−1 个单元格”</h3>
<p>浏览器按你写的 <code><td> 数量逐列排布,<code>colspan="3" 不是加宽,是声明“我覆盖 3 列”,意味着这一行后续不能再出现 2 个独立 <td>(否则总列数超预期)。
<ul><li>若整行应为 5 列,你在第一个 <code><td> 写 <code>colspan="3",那这行最多还能写 2 个 <td>(3+1+1=5),不能写 3 个
<li>
<code>colspan 值必须是纯正整数,colspan="2px" 或 colspan="two" 会被浏览器忽略
border-collapse: collapse 时错位更明显,因为边框会挤到错误位置验证每行真实列数是否一致
手动数容易出错,尤其在嵌套或动态生成表格时。可以用这行 JS 快速校验:
Array.from(tr.children).reduce((s, el) => s + (el.colSpan || 1), 0)
对每个 <tr> 运行它,结果必须全相同。不一致就说明某行多写了 <code><td> 或漏删了。
<ul><li>常见反例:<code><tr>
<td colspan="3">A</td>
<td>B</td>
<td>C</td>
<td>D</td>
</tr> → 实际列数是 6(3+1+1+1),但下一行若只写 4 个 <td>,必然错位
<li>表头 <code><thead> 和数据体 <code><tbody> 的列数也必须对齐,它们是独立容器,但列坐标共享
<h3>colspan 在表头(<code><th>)和普通单元格(<code><td>)中行为完全一致
<p>别以为 <code><th> 可以“例外”——它和 <code><td> 一样受 <code>colspan 控制,且同样需要删减后续单元格。
- 典型场景:一级表头跨多列,二级表头分列细化。例如
<th colspan="2">成绩</th> <th>总分</th>,对应下方就得有两列具体科目 + 一列总分 - 如果
<th colspan="2"> 后跟了 3 个 <code><td>,那一行实际是 2+3=5 列,但视觉上可能只看到 4 个内容区——第 2 列被“吞”了却没删,导致错位 <p>真正难的不是写 <code>colspan,是同步删掉被占位的那些<td>。很多人盯着目标单元格改属性,却忘了扫一眼同一行后面还剩几个 <code><td> ——这个动作必须肉眼确认,不能靠感觉。</td>
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











