正确做法是用和语义化分组、scope属性明确行列关系、价格用包裹、保持dom完整不隐藏。

直接用 <thead> 区分表头、<code><tbody> 按逻辑分组数据行,再配合 <code>scope 属性和语义化 <th>,就能让分类清晰可读、可访问、可维护——别靠视觉对齐或空行“假装”分类。
<h3>用 <code><tbody> 划分数据类别,而不是靠空行或 class 名
<p>很多人想展示“基础版”“企业版”“旗舰版”三类价格,就写三个 <code><tr>,中间加个空 <code><tr><td colspan="4"> </td></tr> 隔开。这看着像分类,但 JS 无法识别、屏幕阅读器跳过、CSS 选中困难。
- 正确做法:每个版本包进独立的
<tbody>,并加 <code>class标识用途,比如<tbody class="plan-basic"> <li> <code>document.querySelectorAll('tbody').length能准确返回分类数,tbody.plan-enterprise tr可精准样式控制 - 浏览器即使省略
<tbody> 也会自动补全,但手动写出才能真正“按类操作” <h3> <code>scope属性决定“这个表头管哪一列/哪一行”只用
<th> 不够,不加 <code>scope,辅助工具不知道“企业版”是行名还是列名,“年付”到底对应哪几行价格。分类表格里,行列语义必须明确。- 第一列是产品名称 → 每个
<th scope="row">(如 <code><th scope="row">企业版</th>) - 第一行是计费周期 → 每个
<th scope="col">(如 <code><th scope="col">月付</th>) - 混用
scope="row"和scope="col"后,aria-labelledby自动生效,读屏软件能说出“企业版 月付 ¥499”而非“第3行第2列 ¥499”
价格数字必须包裹在
<span class="price"></span>里把价格当纯文本塞进
<td>,后续加促销标签、多币种切换、动态计算折扣时就得重写整行 HTML。提前结构化,成本几乎为零,收益巨大。 <ul> <li>写成 <code><td> <span class="price">¥499</span>/月</td>,不是<td>¥499/月</td> - 第一列是产品名称 → 每个
- 这样 CSS 可单独给
.price加粗、变色、加text-decoration: line-through - JS 获取价格只需
row.querySelector('.price').textContent,不怕单位干扰 - 如果要支持汇率换算,只改
.price内容即可,不用动<td> 结构 <h3>移动端保留全部 DOM,靠 CSS 重排而非隐藏列</h3> <p>常见错误是用 <code>@media直接display: none掉“年付”列,结果屏幕阅读器跳过、打印时消失、JS 读不到原始数据。分类表格尤其不能删结构。- 保持所有
<th> 和 <code><td> 在 DOM 中,哪怕在小屏下视觉上折叠 <li>用 <code>flex-direction: column+order重排单元格顺序,或用grid-template-rows控制显示流 - 必要时加
aria-hidden="true"配合视觉隐藏,但绝不移除元素 - 测试点:打开系统朗读功能,确认“基础版 年付 ¥999”仍能被完整播报
最容易被忽略的是
<tbody> 的显式书写和 <code>scope的强制使用——它们不改变页面外观,却决定了表格能否被 JS 精准操作、被辅助技术正确理解、被后续需求平滑扩展。结构没立住,后面所有样式和交互都是在补漏。 - 保持所有
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











