rowspan是声明式占位而非拉高单元格,必须写在起始行对应或中,值不超过剩余行数,被跨行须彻底省略该列而非留空,混用colspan时需确保行列总数守恒。

rowspan 不是“拉高单元格”,而是声明式占位——写错位置或漏删对应 一个 真正难的不是写对 <td>,表格立刻错位。
<h3>rowspan 必须写在起始行的 <code><td> 或 <code><th> 上
<p>它只对当前标签生效,向下锁定列位置。比如要让第二行第一列跨 3 行,<code>rowspan="3" 必须写在第二行那个 <td> 里,不能写在第一行(会多占一行)、也不能写在第四行(没剩余行可跨)。
<ul>
<li>常见错误:写在最后一行 → 渲染高度仍是 1 行</li>
<li>rowspan 值必须 ≤ 当前行到表格末尾的剩余行数(含当前行),超限时浏览器按实际剩余行数渲染,但语义已损坏</li>
<li>它不改变当前行高度,只是“预占”后续行中同一列的位置</li>
</ul>
<h3>被跨过的行必须彻底省略对应列的 <code><td>
<p>不是留空,不是写 <code><td></td>,是整行里直接不生成这个 <td>。否则浏览器会补全单元格,导致列偏移、<code>table.rows[i].cells.length 拿不到预期值、JS 操作失准。
<tr>
<td rowspan="3">A</td>
<td>B1</td>
</tr>
<tr><td>B2</td></tr>
<tr><td>B3</td></tr>
<tr>
<td rowspan="3">A</td>
<td>B1</td>
</tr>
<tr>
<td></td>
<td>B2</td>
</tr>(空 <td> 会占位)
<li>动态生成时最容易漏:服务端模板或 JS 拼接需提前统计连续重复行数,并在非首行跳过该列渲染</li>
<h3>和 <code>colspan 混用时,行列总数必须严格守恒
<td rowspan="2" colspan="2"> 占据 2×2=4 个逻辑单元格,后续两行中,对应这两列的位置都必须跳过——少跳一个,整行列基准就偏了。
<ul><li>检查方法:用开发者工具选中 <code><table>,看右侧 Layout 面板是否出现 “Collapsed cells” 警告
<li>每行 <code>cellIndex 应该从 0 开始连续递增;若中间断开,说明某处漏了 <td> 或多写了
<li>复杂布局(尤其带嵌套分组)优先考虑 CSS Grid 或 Flex,语义更清晰、维护成本更低</li>
<h3>动态渲染时,rowspan 值不能靠猜,得靠算</h3>
<p>React/Vue/JS 拼接表格时,不能在模板里靠 <code>v-if 或 {condition && <td rowspan="{n}">} 临时判断——容易漏掉隐藏的 <code><td>,导致结构断裂。
<ul>
<li>正确做法:先聚合数据,例如用 <code>reduce 统计每组 label 的行数:numRowsByLabel = data.reduce((acc, row) => { acc[row.label] = (acc[row.label] || 0) + 1; return acc; }, {})
rowSpan 的 <td>,其余行跳过该列
<li>注意:React 中不可依赖闭包外变量标记“是否首行”,必须在每组内重置 <code>isFirstRow = true
rowspan,而是当表格行数可能变化时,如何确保每次渲染都同步更新占位数并精确跳过对应列——漏一次,整张表就偏了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











