html文档结构中的语义化地标角色由原生标签隐式提供,而非role属性定义;→banner(仅当为直接子元素)、→navigation、→main(全局唯一且不可嵌套)、→complementary、→contentinfo(仅当属层级),显式role仅用于旧项目补救或区分同类型地标,且必须使用wai-aria标准值。

直接说结论:HTML文档结构中的语义化地标角色,不是靠role属性“定义”出来的,而是由原生语义标签(如<header></header>、<nav></nav>、<main></main>)隐式提供;显式写role仅用于补救场景,且必须严格匹配WAI-ARIA枚举值,否则无效。
哪些标签自带地标角色?
浏览器和辅助技术会自动把以下HTML5标签映射为对应地标角色,无需手动加role:
-
<header></header>→banner(注意:仅当作为直接子元素时才被识别为页面级banner;嵌套在<article></article>里的<header></header>是局部标题,不构成地标) -
<nav></nav>→navigation -
<main></main>→main(一个页面只能有一个,且不能嵌套在<article></article>或<section></section>里) -
<aside></aside>→complementary -
<footer></footer>→contentinfo(仅当属于层级时)
常见错误:用<div class="nav">再加<code>role="navigation"——这不如直接用<nav></nav>简洁可靠,还多了一层出错可能。
什么时候必须显式写 role?
只有两种合理场景需要手写role:
- 旧项目无法改结构,只能在
<div>上打补丁,比如<code><div role="main">(但必须确保该<code><div>确实是唯一主内容区) <li>需要区分多个同类型地标,例如页面有顶部主导航和页脚次级导航:<code><nav aria-label="主导航"></nav>和<nav aria-label="友情链接"></nav>;若用role="navigation"却没配aria-label,屏幕阅读器只会读“导航”,跳转时无法区分 - 不要把
<article></article>当<main></main>用:一个博客列表页,<main></main>应包裹整个文章列表+分页,而不是每个<article></article>都套一层<main></main> - 不要在
<main></main>里塞无关内容:广告、侧边推荐、版权声明都不该出现在<main></main>内部 -
<article></article>可以有自己的<header></header>和<footer></footer>,但它们不生成新的地标角色,只是局部语义容器
硬编码非法role(如role="top-nav")会被完全忽略——浏览器不报错,但辅助技术收不到任何信息。
main 和 article 的语义冲突怎么避?
<main></main>代表整个页面中对用户价值最高的那块内容,而<article></article>是可独立分发的自包含内容单元。两者定位不同,混用容易破坏地标逻辑:
真正容易被忽略的是:即使视觉上<main></main>用了position: absolute脱离文档流,也必须保证它在DOM顺序中仍处于逻辑主内容位置——否则屏幕阅读器会按源码顺序播报,而非视觉顺序。











