saas定价页必须用原生而非div+grid,因其提供唯一正确的二维数据语义;需严格使用、scope属性、语义化隐藏列、css驱动高亮与数字对齐,确保可访问性、打印、导出及响应式正确。

用 <table> 做 SaaS 定价页,不是“可以”,而是“必须”——只要你的数据是二维对比(功能 × 套餐),就别碰 <code>div + grid 模拟表格。语义错、读屏崩、打印断行、Excel 导出失败,全是绕开原生 <table> 的直接后果。
<h3>为什么 pricing 表不能用 div + CSS Grid 布局</h3>
<p>常见错误现象:屏幕阅读器读出“盒子、盒子、盒子”,而不是“企业版|API 访问|✓”;Chrome 打印预览中某行被截成两页;用户复制价格粘贴进 Excel,所有内容挤在 A1 单元格里。</p>
<p>根本原因在于,<code>div 没有行列语义,辅助技术无法建立“第 3 列=价格”“第 2 行=专业版”的映射关系。而 SaaS 定价表本质就是结构化二维数据,<table> 是浏览器唯一原生支持该语义的标签。
<p>实操建议:</p>
<ul><li><code><thead> 必须只放列标题,每个 <code><th> 加 <code>scope="col",例如 <th scope="col">专业版</th>
<tbody> 每个 <code><tr> 对应一个套餐,不嵌套、不省略
<li>禁用 <code>colspan/rowspan —— 它们会破坏 :nth-child() 的列索引连续性,导致移动端样式错位或推荐标识联动失效移动端隐藏非核心列时,display: none 不等于删 DOM
很多方案在 @media (max-width: 768px) 里对整列 td 和对应 th 写 display: none,结果屏幕阅读器照样读、打印仍出错、SEO 爬虫看到空列。
正确做法是只隐藏视觉,保留语义结构。关键点在于:列头 <th scope="col"> 和数据单元格 <code><td> 必须共用同一套选择器逻辑。
<p>实操建议:</p>
<ul>
<li>给要隐藏的列统一加 class,比如 <code>class="hide-on-mobile"
th.hide-on-mobile, td.hide-on-mobile { display: none; }
th:nth-child(4) { display: none; } —— 这样 td 没同步隐藏,语义断裂<div style="overflow-x: auto">,而非删减列
<h3>让“推荐”套餐高亮,纯 CSS 就够,别写 JS 切换</h3>
<p>硬塞 <code>class="popular" 再用 JS 控制样式,既增加首屏 JS 体积,又破坏 SSR 可访问性。现代浏览器已支持 :has(),完全可驱动动态标记。实操建议:
- 给推荐列的
<th> 加 <code>data-popular="true",例如<th scope="col" data-popular="true">企业版</th> - CSS 用:
th[data-popular="true"]::before实现角标,th[data-popular="true"] ~ td:nth-child(3)联动高亮该列所有单元格 - 注意兼容性:Safari 15.4+、Chrome 105+ 支持良好;若需 IE11 或旧 Edge,改用
class="plan-popular"手动维护,但别强求 CSS 驱动 - 价格数字单独包裹
<strong></strong>或加class="price-amount",例如<td class="price"> <strong>¥299.00</strong>/年</td> - CSS 用
text-align: right+font-variant-numeric: tabular-nums强制等宽数字对齐 - 列样式优先用
td:nth-child(n),但注意序号从整表 DOM 数起(包括<thead> 中的 <code><th>) <li>避免用 <code>padding-left模拟右对齐——它不解决小数点错位问题
价格数字右对齐和小数点对齐,靠 CSS 不靠空格
写 <td> ¥99.00</td> 是典型反模式:缩放后空格失效、复制进 Excel 多出不可见字符、等宽字体切换后错位。
价格列需要真正“跳出来”,靠的是列级控制,不是给每个单元格打补丁。
实操建议:
最易被忽略的一点:所有 <th> 必须带 <code>scope 属性,且 <thead> 和 <code><tbody> 必须显式写出。很多人以为省略它们只是“代码洁癖”,其实这是屏幕阅读器能否正确播报“第 2 列是企业版价格”的分水岭。没写,就等于没做可访问性。</tbody>











