在进行前端无障碍审计时,不少开发者会遇到一个奇怪的场景:浏览器不报错,但Lighthouse却直接标红“duplicate-main”。这其实是语义层与渲染层之间的根本差异。

为什么浏览器不报错但 Lighthouse 直接标红 duplicate-main
关键原因就在于:`main` 是语义锚点,不是渲染指令。浏览器只管解析和绘制,而辅助技术(如 VoiceOver、NVDA)和审计工具(Lighthouse、axe)会严格校验结构语义。当页面中间出现多个 `
` 时,读屏器按 M 键跳转,结果很可能出错——要么直接跳过全部主内容,要么随机选一个播报,或者反复念“主内容开始”。用户根本无法稳定地进入正文。这可不是小问题。
日常开发中,几个典型的翻车场景值得注意:
- 在 React/Vue 项目里,每个页面组件都写 `
{children}`,hydration 后 DOM 真实残留了多个实例。
- 服务端模板(EJS/Twig)没有做路由判断,列表页和详情页共用同一套 `
` 包裹逻辑。
- SPA 路由切换后,旧的 `` 节点没被移除,新节点只是插入进来,两者并存。
怎么快速确认页面只有一个 ``
“看起来只有一个”是远远不够的,必须亲手验证。方法并不复杂:
1. 打开开发者工具(F12),切换到 Elements 面板,按 `Ctrl+F`(Windows)或 `Cmd+F`(macOS)搜索 ``。
2. 只应该匹配到一对 `` 和 ``。特别注意:自闭合写法 `` 是无效 HTML,也会被计为一个错误实例。
3. 右键匹配到的节点,选择 “Reveal in Elements panel”,检查它的直接父元素是不是 ``。如果父级是 `` 或 `