必须用<table>做价格对比表,因其原生支持行列语义、可访问性好、打印稳定;需正确使用<thead><th scope="col/row">、移动端用data-label重构为纵向卡片、价格数字右对齐并用class高亮差异。
直接用 <table> 就能做出清晰、可访问、响应式的价格对比表,不需要框架或 JS 拼接结构——关键在语义分层、CSS 控制和移动端重构逻辑。
<table> 而不是 div 或 grid
价格对比本质是「行=参数项、列=版本方案」的二维结构,<table> 是浏览器唯一原生支持行列语义、屏幕阅读器可正确解析、打印/PDF 导出不崩、Safari 15 以下也稳的方案。
div 横向堆套餐,小屏换行后,“基础版”的“API 限额”会和“企业版”的“SLA 等级”对不上,视觉和逻辑全错位display: grid 写死 grid-template-areas,加一个新版本就得重写所有区域定义,维护成本陡增min-width: 0 + overflow: hidden,长文本如“含 24 小时人工客服 + SLA 99.9%”直接撑破整列<thead> 和 <th scope> 怎么写才不翻车表头不是装饰,是辅助技术读取和 CSS 定位的基础。第一行必须进 <thead>,且每个版本名用 <th scope="col">;第一列每个参数名(如“月费”“并发数”)用 <th scope="row">。
<td>基础版</td><td>专业版</td> → 屏幕阅读器读作“第一行第一列:基础版”,无法识别这是列标题<th scope="col" class="plan-basic">基础版</th>,后续 CSS 可用 .plan-basic ~ td:nth-child(2) 精准控制该列样式<td> 填 - 或 <span data-status="pending">待上线</span>,别留空或删单元格加 overflow-x: auto 到 <table> 没用,用户得手动拖,还容易误触缩放。真解法是媒体查询主动重构 DOM 渲染顺序:小屏下把“横向对比”转为“纵向卡片”。
立即学习“前端免费学习笔记(深入)”;
data-label:<td data-label="月费">¥99</td>,小屏 CSS 用 ::before { content: attr(data-label) ":"; } 补前缀.comparison-table { display: block; }.comparison-table tr { display: block; margin-top: 1em; }.comparison-table td, .comparison-table th { display: block; padding: 0.5rem 0; }.comparison-table td::before { content: attr(data-label) ":"; font-weight: bold; }
用户扫一眼就要比出贵贱,数字右对齐、小数点上下对齐、货币符号位置统一,直接影响可信度;多版本差异不能靠 inline style,得用 class 控制。
<td class="price"><span class="amount">99</span><span class="currency">¥</span></td>,CSS 设 .amount { font-feature-settings: "tnum"; } 强制等宽数字<td class="diff-up">+12%</td>,CSS 定义 .diff-up { color: #e74c3c; },后续加暗色模式只需改一处colspan 合并价格单元格——会破坏 nth-child() 定位逻辑,导致高亮错列最易被忽略的是数据契约对齐:新版加了 updated_at 字段,旧模板直接 data.updated_at 会报 Cannot read property 'updated_at' of undefined。模板里必须写 data?.updated_at ?? '—',或者抽成映射函数统一处理字段缺失。