加载指示符必须位于main标签内部且仅为临时占位,不可替代主体内容;main仅承载唯一核心语义,状态变化须由js控制dom更新,严禁外置、残留或混用可复用元素。

main 标签不负责表达“状态”,只承载“主体”
-
✅ 合理做法:
- 初始渲染时,
内放一个轻量级加载指示符(如 ),同时设置 aria-live="polite" 或 role="status" 便于读屏器感知变化;- 数据就绪后,用 JS 替换整个 loading 区域为真实内容(标题、正文、操作按钮等);
- 确保替换后,
里只保留与当前 URL 强相关、不可跨页复用的内容。 ❌ 常见错误:
- 把加载指示符放在
外(如塞进 或独立 ),导致屏幕阅读器无法将其与主内容上下文关联;- 多个路由共用同一套模板,每个都渲染
,造成 SPA 中残留多个 ,而加载指示符恰好卡在其中一个里; - 加载完成却不移除占位符,或把 loading 元素和真实内容并存于
中,稀释语义焦点。 加载指示符必须服从
的语义边界 不是容器盒子,而是语义锚点。因此: - 它里面可以有
、 、 等组织单元,但所有子元素都必须服务于“当前视图的不可复用主体”这一目标;- 加载指示符只是过渡态视觉反馈,不应包含导航链接、页脚版权、全局搜索框等可复用内容;
- 若使用骨架屏(skeleton),建议用语义中立的
包裹,避免误用或 嵌套其中——这些标签一旦出现,就会干扰辅助技术对 内结构的理解。 实际验证要点
- 打开开发者工具 → Elements 面板 → Ctrl+F 搜索
<main></main>,确认只有一个,且父节点是; - 展开该
,检查是否含有非主体内容(如面包屑、登录入口、底部联系方式); - 在加载状态下触发 VoiceOver 或 NVDA,听是否播报“主内容开始”后立即读出 loading 提示(理想路径);
- Lighthouse 运行无障碍审计,确保无 “
is not a top-level element” 或 “Document has more than one element”。
不复杂但容易忽略
- 多个路由共用同一套模板,每个都渲染
- 初始渲染时,











