定价表必须用<table>而非div布局,因其语义正确、打印不折行、屏幕阅读器可读;需写全<thead><tbody>、每个<th>加scope="col";价格列用CSS右对齐和等宽字体,移动端用容器包裹实现横向滚动。

用 <table> 做定价表最稳妥,别碰 div + CSS Grid 模拟表格——语义错、打印错行、屏幕阅读器读不懂,纯静态场景下没理由绕开原生表格。
为什么定价表必须用 <table> 而不是 div 布局
定价表本质是行列明确的结构化数据:产品名、功能项、价格、是否包含,每一列有固定含义,每行代表一个方案。浏览器和辅助技术(如屏幕阅读器)靠 <table> 的语义自动建立行列关联;div 堆出来的“表格”只是视觉像,DOM 里全是扁平盒子,无法被正确解析为“第2列是价格”“第3行是企业版”。打印时也常出现跨页断行错位,因为 div 没有原生分页控制能力。
常见错误现象:
- 用户用读屏软件访问,听到的是“盒子、盒子、盒子”,而不是“专业版,价格列,¥199.00”
- Chrome 打印预览中,某一行被截成两页,第二页只剩价格没产品名
- 导出 Excel 时,所有内容挤在 A1 单元格里——因为没
<table>结构,JS 库无法识别行列关系
<thead> 和 <tbody> 必须写全,scope="col" 不能省
只写 <table><tr><th>基础版</th><th>专业版</th></tr><tr><td>✓</td><td>✓</td></tr></table> 是无效语义。缺少 <thead> 和 <tbody>,辅助技术无法区分表头与数据;不加 scope="col",屏幕阅读器不知道这个 <th> 是管整列还是仅当前单元格。
立即学习“前端免费学习笔记(深入)”;
实操建议:
- 表头行必须包在
<thead>里,数据行必须包在<tbody>里 - 每个
<th>都要带scope="col",例如<th scope="col">专业版</th> - 如果某列需要“合并标题”(比如“服务支持”下分“响应时间”“SLA”),用
<th scope="rowgroup">+ 嵌套<tbody>,而非colspan
价格列右对齐和小数点对齐,靠 CSS 不靠空格
很多人在 HTML 里写 <td> ¥99.00</td> 试图右对齐,结果换字体或缩放后全乱。空格不可靠,且复制粘贴会丢空格或引入全角字符,导致 Excel 导入失败。
正确做法:
- 给价格列统一加 class,例如
<td class="price">¥128.00</td> - CSS 写死对齐和等宽字体:
.price { text-align: right; font-family: "Consolas", "SFMono-Regular", monospace; } - 要小数点严格对齐(¥99.00 和 ¥1280.00 底部对齐),加
font-variant-numeric: tabular-nums;——注意 Safari 14 及更早版本不支持,但价格列本身对齐误差影响不大 - 禁用
text-align: center给价格列——用户扫视时,右对齐比居中更快定位数值大小
移动端窄屏下横向滚动必须用容器包裹,不能直接设 <table> 样式
<table style="overflow-x: auto"> 完全无效,因为 <table> 默认是 inline-table 行为,不触发块级滚动。用户滑动不了,只能左右拖拽整个页面。
实操方案:
- 用
<div class="table-container">包住整个<table> - CSS 必须写两处:
.table-container { overflow-x: auto; -webkit-overflow-scrolling: touch; }和.table-container table { min-width: 600px; } -
min-width值要根据实际列数估算(一般 4 列起步设 600px),太小不触发滚动,太大导致小屏用户要拖很久 - 不要用 JS 动态切换为垂直卡片——“简单定价表”需求下,这是过度设计,反而增加首屏加载和逻辑复杂度
真正容易被忽略的点是 UTF-8 BOM:用户点击“导出 Excel”,打开乱码,八成是因为生成的 CSV 或 HTML 文件没带 BOM 头,Excel 默认按 ANSI 解码。哪怕你 CSS 写得再准,导出环节卡在这一步,整个定价表就失去业务价值。



















