语义标记是无障碍评分的硬性门槛,非加分项;Lighthouse对<main>缺失、<h1>跳级、<label>未关联等直接标“严重”失败,因其破坏读屏器导航锚点、标题逻辑树及表单上下文识别。

语义标记不是“加分项”,而是无障碍评分的硬性门槛——Lighthouse 无障碍审计中,<main>缺失、<h1>层级跳变、<label>未关联输入框,直接触发「严重」级失败项。
为什么 <main> 缺失会让 Lighthouse 扣分
浏览器和读屏器把 <main> 当作内容定位锚点。没有它,用户无法用快捷键(如 NVDA 的 m 键)直跳主内容,必须逐个 tab 或线性听完整页导航栏。Lighthouse 检测到页面无 <main>,会直接标为「Landmark 不完整」。
- 不能用
<div id="main">替代:它只是普通容器,无隐式role="main" - 每个页面只能有且仅有一个
<main>;重复出现会被部分读屏器忽略 -
<main>不能嵌套在<header>、<nav>、<footer>内,否则语义层级断裂,键盘 Tab 流可能跳过它
<label> 关联失效的三种典型写法
表单是无障碍高频失败区。<label> 不只是视觉装饰,它是屏幕阅读器播报输入上下文的唯一可靠依据。
- 写成
<div>用户名</div><input type="text">:完全无关联,读屏器只报“编辑框”,不读“用户名” - 写了
for但id不匹配:<label for="user">用户名</label><input id="username">→ 关联失败 - 用
aria-label覆盖<label>:<label>密码</label><input aria-label="Password">→ 屏幕阅读器优先读aria-label,丢弃可见文本,多语言站点立刻翻车
标题层级(<h1>–<h6>)怎么错就怎么扣分
标题结构是读屏器用户最依赖的导航路径。Lighthouse 会检查是否跳级、是否缺失 <h1>、是否多个 <h1>。
立即学习“前端免费学习笔记(深入)”;
- 禁止
<h1>后直接<h3>:跳级破坏逻辑树,NVDA 的标题导航模式会漏掉该层级 - 每个页面必须有且仅有一个
<h1>:多个<h1>会让读屏器误判页面主题分散 - 别用
<div class="h2">模拟标题:CSS 改样式,但语义仍是 div,读屏器读作“组”,不是“二级标题”
什么时候必须用 <table> 而不是 display: grid
当内容本质是二维关系(比如评分量表、课程课表、问卷矩阵),<table> 不是过时选择,而是语义刚需。CSS Grid 只管布局,不提供行/列头关联能力。
- 读屏器对
<table>自动启用表格导航模式(方向键可行列移动),grid容器里全是平铺<div>,无法建立“第2行第3列对应问题B选项+1”这种语义 - 必须配
<thead>和<th scope="row">/<th scope="col">,否则屏幕阅读器无法联动播报行列上下文 - 若强行用
grid+aria-rowindex等手动模拟,维护成本高、兼容性差,主流读屏器(如 VoiceOver 17+)仍不识别
语义标记的坑不在「会不会写」,而在「改了视觉却忘了 DOM 结构」——响应式菜单折叠后 <nav> 仍在 DOM 中但被 display: none,键盘焦点依然能进入;JS 动态渲染内容没补 aria-live,更新完全静默。这些细节,才是真实评分卡点所在。



















