复杂表头必须先计算逻辑格子数,即每行colspan值之和(默认1)须恒等于总列数,否则表格结构崩坏;thead/tbody为语义刚需,缺失则WCAG不合规;响应式应外包div控制滚动,动态生成需实时校验格子数。
HTML表格崩坏的根源,90%出在第一行就数错了列数。比如设计是6列宽的报表,<th colspan="2">收入</th><th colspan="2">支出</th><th>备注</th>这行加起来是2+2+1=5格——少1格,整张表后续所有行都会右移或塌陷。
<table>,看rows[0].cells.length是不是你预设的总列数colspan值之和(没写colspan默认为1)必须恒等于总列数rowspan不参与本行计数,但它会“吃掉”下一行对应位置的单元格——下一行同一列必须跳过写td或th
rowspan="2"、哪些要colspan="3"
把所有<tr>都塞进一个<table>里,浏览器会自动补<tbody>,但屏幕阅读器和Excel导出根本不知道哪是表头、哪是数据。财务报表一旦缺<thead>,WCAG 2.1直接不合规。
<thead>只放真正表达维度的<th>,比如“部门”“Q1销售额”;数值列用<td>
<tbody>里禁止出现rowspan跨到<thead>——HTML规范不支持,Chrome可能渲染,IE直接空白<thead>必须单独包裹,且父容器需设display: block和max-height,否则position: sticky无效<caption>声明报表主题,别靠CSS居中标题文字——这是唯一被屏幕阅读器识别为“表格标题”的语义节点给<table>加width: 100% + overflow-x: auto基本没用。表格会优先满足内容宽度,溢出部分被裁剪且无法滚动,用户根本拖不动。
<div style="overflow-x: auto;">包住整个<table>,让滚动由容器控制table-layout: fixed除非你已加word-break: break-all——否则长数字或URL会把整列撑爆colspan超过3列:小屏下合并后内容挤成一团,可读性归零<details>折叠次要列,而不是强行横向滚动服务端或JS拼接HTML时,如果先输出<th rowspan="3">收入</th>,再在后续行里漏掉跳过对应位置,DOM结构就已损坏。浏览器可能渲染出来,但Excel导出、打印分页、屏幕阅读器都会错乱。
立即学习“前端免费学习笔记(深入)”;
colspan总和是否达标rowspan="n",要在内存中标记接下来n-1行的该列位置为“已占用”,生成时跳过<td colspan="{{colCount}}">这种动态值——万一colCount算错,整行就废了document.querySelectorAll('table tr').forEach(...)检查每行cells.length是否一致,不一致立刻报错中断colspan,而是写完之后没人去数那一行到底有没有凑够格子。只要有一行漏数,整张表就在逻辑上已经坏了——样式再好看也没用。