html5结构标签是无障碍基础,需语义正确、嵌套合理并与aria协同;其被屏幕阅读器识别为地标区域以支持快捷导航,但依赖浏览器支持与规范使用,滥用或冗余role会损害体验。

HTML5结构标签本身不能自动提升无障碍访问,但它们是实现良好无障碍体验的必要基础——前提是语义正确、嵌套合理,并与ARIA协同而非覆盖或冲突。
为什么<header></header>、<nav></nav>这些标签对屏幕阅读器有用
主流屏幕阅读器(如NVDA、VoiceOver)会将<header></header>、<nav></nav>、<main></main>、<aside></aside>、<footer></footer>等识别为“landmark regions”(区域地标),用户可通过快捷键(如D键在NVDA中跳转地标)快速导航。但这依赖两个前提:
- 浏览器必须支持HTML5语义解析(现代浏览器均支持,IE9+部分支持,IE8及以下完全不识别)
- 标签不能滥用:比如把
<section></section>当<div>用,或在<code><nav></nav>里塞广告链接,反而干扰用户判断role属性什么时候该加,什么时候不该加多数HTML5结构标签已有隐式ARIA role(例如
<nav></nav>等价于role="navigation"),显式重复添加不仅冗余,还可能覆盖浏览器默认行为。只有在以下情况才需手动加role:- 使用非语义容器(如
<div>)模拟结构功能,且无法改用原生标签时,例如:<pre class="brush:php;toolbar:false;"><div role="navigation">...</div></pre> <li>需要覆盖默认role(极少见),比如把<code><article></article>临时标记为role="region"并配aria-labelledby - 动态内容加载后,DOM结构未更新但逻辑角色已变(如某
<section></section>从普通内容区变为当前操作面板),此时可补role="application"等
反例:
<nav role="navigation"></nav>
——这是典型冗余,可能在旧版JAWS中引发双播报。立即学习“前端免费学习笔记(深入)”;
aria-labelledby和aria-label选哪个优先用
aria-labelledby,它复用页面中已有的可见文本作为标签,确保视觉与语音一致;仅当无合适可见文本时,才用aria-label。-
aria-labelledby指向一个或多个id,适合<main></main>、<aside></aside>等有标题的区域:<h2 id="related-articles">相关文章</h2> <aside aria-labelledby="related-articles">...</aside>
-
aria-label适合无标题的辅助性区域,如侧边工具栏:<aside aria-label="编辑工具栏">...</aside>
- 避免同时使用两者,
aria-label会直接覆盖aria-labelledby
容易被忽略的嵌套与焦点管理问题
结构标签不解决键盘焦点流问题。即使用了
<main></main>,如果内部按钮不可聚焦(如<div tabindex="-1">),或跳过关键交互元素,屏幕阅读器用户仍会迷失。 <ul> <li> <code><main></main>应包含首个可聚焦元素(如搜索框、主按钮),否则用户进入页面后可能停在空白处 - 使用非语义容器(如
- 动态显示的
<aside></aside>或<dialog></dialog>需手动管理焦点:显示时focus()到首元素,关闭时返回触发点 - 不要用
display: none隐藏结构区域——这会让整个区域从无障碍树中消失;改用aria-hidden="true"配合视觉隐藏类
真正的无障碍不是堆砌标签,而是让每个结构标签背后都有清晰的导航意图和可控的交互路径。











