<main>必须全局唯一且仅包裹核心内容,因其是屏幕阅读器“M键跳转”的唯一锚点;多个或混入非主内容会导致定位错误、正文被忽略,正确做法是全页仅一个<main>,内部只含用户真正需阅读/操作的部分。

语义化 HTML 不是“加分项”,而是可访问性失效时最先被追责的技术底线。 一旦屏幕阅读器无法跳转到 <main>、表单控件没绑定 <label>、或标题层级断裂,用户根本进不了内容区——这不是体验问题,是功能缺失。
为什么 <main> 必须全局唯一且只包核心内容
它是屏幕阅读器“M 键跳转”的唯一锚点。多个 <main> 或包裹 banner、菜单、弹窗,会导致读屏工具跳过正文、定位错误,用户得手动听完整页才能找到要操作的部分。
- Next.js 布局组件里写一个
<main>,子页面又渲染一个 → 实际 DOM 出现两个,第一个生效,第二个被忽略 -
<main>里塞了顶部导航栏 + 左侧菜单 + 文章正文 → 屏幕阅读器把导航和菜单当“主内容”播报,正文反而被淹没 - 正确做法:全页面只出现一次
<main>,且内部仅包含用户真正要阅读/操作的部分(如商品列表、表单主体、文章段落)
<section> 和 <article> 不是 <div> 的高级替代品
它们有明确的结构约束:<section> 要有标题(<h2>–<h6>),<article> 必须能独立分发(RSS、邮件推送)。滥用会污染文档大纲,让屏幕阅读器生成大量无意义导航节点。
- 错误:
<section><p>欢迎关注我们</p></section>(无标题、不可分发、无结构意义) - 判断标准:这块内容是否自带标题?能否被 RSS 抓取?是否已有更精确语义标签(比如页脚用
<footer>)? - SEO 影响:Google 参考文档大纲评估权重,标题层级断裂或节点泛滥会弱化主内容识别
表单控件不绑定 <label> 是最常被忽略的致命漏洞
没 <label> 的 <input> 在屏幕阅读器中无法被朗读字段含义,键盘用户也无法通过 Tab 键聚焦后获得上下文提示。后期用 JS 补救(如监听焦点事件动态插入 ARIA)会增加运行时开销和维护风险。
立即学习“前端免费学习笔记(深入)”;
- 必须显式绑定:
<label for="email">邮箱</label><input id="email" type="email"> - 或嵌套写法:
<label>邮箱<input type="email"></label> - 避免用
title替代<label>:不是所有读屏支持title,且它不参与焦点管理 -
<fieldset>+<legend>必须用于单选/复选集合,否则分组逻辑丢失,残障用户无法理解选项关系
图片缺失 alt 会触发隐性性能问题
表面看只是可访问性缺陷,实际常迫使开发者后期注入 JS 逻辑补救——比如监听图片加载失败后手动播报描述、动态添加 aria-label。这些额外操作不仅增加 bundle 体积,还会拖慢语音导航响应。
-
<img>必须有alt:装饰图设为空字符串alt="",内容图需准确描述信息 - 图文组合用
<figure>包裹,<figcaption>必须与<img>同级且存在 - 避免用 CSS 视觉对齐代替语义绑定:隐藏
<label>但不移除其语义作用,比纯视觉模拟更可靠
最容易被忽略的不是“该用什么标签”,而是“这个标签在当前上下文是否承载了它本该承载的内容”。一个 <h2> 放在 <footer> 里,或 <nav> 里塞了广告链接,语义就崩了——机器不会报错,但人和辅助技术已经找不到路了。



















