<main>必须且只能出现一次,嵌套在<nav>里会破坏可访问性,导致屏幕阅读器无法准确定位主体内容、快捷键失效、搜索引擎降权;<nav>需用aria-label区分多个导航区;交互元素须用原生语义标签或补全tabindex、role与键盘事件;标题层级须严格遵循<h1>至<h6>嵌套逻辑,避免隐藏内容未加aria-hidden。

<main></main> 必须且只能出现一次,嵌套在 <nav></nav> 或 <section></section> 里会直接破坏可访问性逻辑——屏幕阅读器将无法准确定位页面主体内容。
为什么 <main></main> 不能嵌套在 <nav></nav> 里
很多开发者误以为“导航后的区域就是主要内容”,就把 <main></main> 套进 <nav></nav>。但规范明确要求:<main></main> 是页面级语义容器,代表整个文档的主导航后、页脚前的唯一核心区域;<nav></nav> 是可复用的导航单元,可能出现在页脚、侧边栏甚至弹窗里——这些地方显然不该包裹 <main></main>。
实际影响包括:
- NVDA、VoiceOver 的“跳转到主要内容”快捷键(如 Ctrl+Alt+O)失效
- 辅助工具报错:
ARIA: main role must not be a descendant of another landmark - 搜索引擎可能降权,因结构歧义导致内容权重分散
<nav></nav> 的 aria-label 不是可选项
当页面含多个导航区时,只写 <nav></nav> 却不加 aria-label,屏幕阅读器用户听到的只会是 “navigation, navigation, navigation…” 完全无法区分。
立即学习“前端免费学习笔记(深入)”;
正确做法:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 主导航:
<nav aria-label="主导航"></nav> - 页脚链接:
<nav aria-label="友情链接"></nav> - 面包屑:
<nav aria-label="当前位置"></nav> - 移动端抽屉菜单:
<nav aria-label="侧边菜单"></nav>
避免用 aria-labelledby 指向 display: none 的隐藏标题——应使用可见标题或显式文本。
键盘焦点必须由原生语义元素承载
用 <div onclick="https://www.php.cn/link/263b1243ca2dbeb358777ceabc4a2e4c"> 模拟按钮,就等于放弃浏览器原生键盘支持:Tab 键无法进入、Enter/Space 无响应、屏幕阅读器不播报角色和名称。
<p>必须优先使用:</p>
<ul>
<li>触发行为 → <code><button></button>(自动有 role="button"、可聚焦、可回车触发)
<a href="https://www.php.cn/link/263b1243ca2dbeb358777ceabc4a2e4c"></a>(自动有 role="link"、可聚焦、可回车跳转)<input>、<select></select>、<textarea></textarea>(自带完整键盘交互逻辑)自定义组件若必须用 <div>,至少补全:<code>tabindex="0" + role + 手动监听 keydown(如 Enter/Space 触发 click)。
标题层级断裂会让键盘用户彻底迷失
很多页面从 <h2></h2> 开始,或在 <main></main> 外堆了三个 <h1></h1>,这会让屏幕阅读器生成错误大纲,用户无法用快捷键(如 H 键)跳转到真正想看的板块。
必须遵守:
- 全页仅一个
<h1></h1>,代表页面主主题(如“关于我们”或“产品首页”) -
<h2></h2>用于划分主要区块(如“服务介绍”“客户评价”) -
<h3></h3>及以下严格嵌套在对应<section></section>内,不得跳级 - 不要用
<h2></h2>做 logo 文字——那是视觉样式问题,应改用<div> + <code>aria-label最易被忽略的是:CSS 隐藏了
<h1></h1>却没加aria-hidden="true",造成视觉与语音双重混乱。


















