必须唯一且只包裹真正需要被聚焦的核心内容,否则屏幕阅读器会跳过、定位错位或反复遍历冗余节点拖慢响应;多个section会导致辅助设备“迷路”,因按M键仅识别第一个合法section,后续被忽略或触发错误导航。

<main></main> 必须唯一且只包裹真正需要被聚焦的核心内容,否则屏幕阅读器会跳过、定位错位,甚至反复遍历冗余节点拖慢响应。
为什么多个 <main></main> 会让辅助设备“迷路”
屏幕阅读器按 M 键跳转时,只认第一个合法的 <main></main>;后续的会被忽略或触发错误导航。常见场景包括:
- Next.js 或 Remix 的布局组件里写了一个
<main></main>,子路由又渲染一个 -
<main></main>包了顶部 banner、左侧菜单、面包屑和正文——这些本该用<header></header>、<nav></nav>、<aside></aside>分离 - SSR 渲染时服务端注入一个
<main></main>,客户端 hydration 又挂载一个
这不是字节膨胀问题,而是 DOM 遍历路径污染:辅助技术必须逐节点检查 role 和 landmark,冗余 <main></main> 会强制它多走几轮判断逻辑。
<section></section> 和 <article></article> 不是 <div> 的语义美化剂
<p>滥用 <code><section></section> 会导致屏幕阅读器生成大量无意义的“区域”导航项,用户无法快速识别主干内容。判断是否该用的关键不是“看起来像一块”,而是:
立即学习“前端免费学习笔记(深入)”;
- 这块内容有没有自己的
<h2></h2>–<h6></h6>?没有就别用<section></section> - 这块内容能否独立分发(比如 RSS 抓取、邮件推送)?不能就不是
<article></article> - 它是否已有更精确的语义标签?比如页脚信息用
<footer></footer>,联系信息用<address></address>,就别套<section></section>
错误示例:<section><p>欢迎关注我们</p></section> —— 无标题、不可分发、无结构价值,纯属增加噪音。
图片与表单的“伪语义”比完全没语义更危险
开发者常以为加了 title 或 CSS 视觉对齐就完成了语义绑定,但实际会触发 JS 补救逻辑,带来运行时开销:
-
title属性不被所有读屏支持,且鼠标悬停才显示,对键盘/语音用户无效;应优先用alt或aria-label - 仅靠 CSS 把 label 文字放在 input 旁边,
focus时读屏听不到关联文本;必须用<label for="id">或嵌套写法 - 用
<div onclick="submit()">模拟按钮,需手动补role="button" tabindex="0" aria-label,而原生<button>自带全部行为
这类“半语义”代码后期维护成本高:一旦交互逻辑变更,JS 补丁容易漏掉 ARIA 同步,导致可访问性回归失效。
最容易被忽略的是标题层级断裂——比如页面从 <h2></h2> 开始、<main></main> 外堆了三个 <h1></h1>、小节用了 <h3></h3> 但主内容还没出现 <h2></h2>。这种结构会让屏幕阅读器的大纲视图完全失序,用户无法用快捷键跳转到预期层级。



















