html文档结构的可访问性由根结构、语义嵌套、焦点路径三层刚性约束决定;省略会导致怪异模式、发音错乱、标签页空白、语义丢失;必须唯一且含标题,不可替代;tab组件需严格遵循role+id+focus同步规则。

HTML框架设计中的可访问性不是靠后期加 aria-label 或 JS 修补出来的,而是由文档根结构、语义标签嵌套规则、焦点流路径这三层刚性约束决定的。跳过任何一层,后续所有“可访问性优化”都只是打补丁。
为什么 、、 不能省略
这不是格式洁癖,而是浏览器解析与辅助技术协同的硬性前提:
-
缺失 → 浏览器进入怪异模式(Quirks Mode),document.documentElement可能为null,JS 获取根节点失败 -
缺失 → 屏幕阅读器发音错乱,尤其中英文混排时读成日语或英语音调 -
中<title></title>缺失 → 页面在标签页显示为空白,视障用户无法识别当前页面身份 -
<meta charset="UTF-8">缺失 → 中文、emoji 渲染为 ,且部分 AT(辅助技术)直接跳过整段内容 -
外写<nav></nav>或<main></main>→ 浏览器自动迁移但语义丢失,JAWS 等工具会忽略其角色,body > header这类 CSS 选择器也失效
<main></main> 和 <section></section> 的职责边界在哪
它们不是视觉分组工具,而是 AT 导航逻辑的锚点:
-
<main></main>必须且只能出现一次,代表整个文档唯一主内容区;AT 用户按Insert+B(JAWS)或Ctrl+Alt+O(NVDA)直接跳转至此 -
<section></section>是逻辑分组容器,可嵌套,但不能替代<main></main>;若把仪表盘整个包进<section></section>,AT 会将其标记为“非核心内容”,跳过不读 -
<main></main>内部必须包含至少一个标题(<h1></h1>–<h6></h6>),否则部分屏幕阅读器认为该区域无意义,直接略过 - 多个
<main></main>或用<div role="main"> 替代 → 触发 WCAG 重复主区域错误,Lighthouse 报 <code>document-has-one-main标签页(Tab)组件的 ARIA 绑定为什么总出问题
关键不在属性是否写全,而在 DOM 结构与焦点管理是否同步:
- 必须用
<ul role="tablist"></ul>包裹所有<li role="tab">,不能用<div> 模拟;否则 AT 无法识别为可切换控件组 <li> <code>aria-controls值必须精确匹配目标<div role="tabpanel"> 的 <code>id,大小写、空格、前缀都不能差 - 激活 tab 后,必须手动
element.focus()到对应tabpanel,且设置tabindex="0";仅靠aria-hidden="true/false"不足以让 AT 重新聚焦 - 方向键切换时,需监听
ArrowLeft/ArrowRight并阻止默认行为,否则焦点会跳出 tablist 区域 - 用
display: none隐藏未激活 panel → AT 仍可能读取其内容;应同时加aria-hidden="true"和inert(现代支持)或tabindex="-1"
可访问性底层架构真正难的不是写对几个属性,而是让 HTML 结构本身成为导航协议——每个标签都在回答“我是什么”“我在哪”“我能被怎么操作”。一旦结构松动,ARIA 就成了贴在裂缝上的胶带。
- 必须用











