html5语义化标签自带隐式aria地标角色,如默认为role="banner",为role="navigation",为role="main",为role="contentinfo",故无需手动添加role属性;仅在语义缺失时(如实现搜索区)才需显式设置role。

为什么不用 role 也能有地标?
因为 HTML5 大部分语义化标签自带隐式 ARIA 角色。比如 <header></header> 默认就是 role="banner",<nav></nav> 对应 role="navigation",<main></main> 是 role="main",<footer></footer> 是 role="contentinfo"。辅助技术(如屏幕阅读器)直接读取这些隐式角色,无需你手动加 role 属性。
常见错误是给 <nav></nav> 再写一遍 role="navigation"——纯属冗余,还可能干扰某些旧版辅助技术的解析逻辑。
- 只有当语义缺失时才显式添加
role:比如用<div class="search-box"> 实现搜索区,就得补 <code>role="search" - HTML4 或无 JS 回退场景下,才考虑用
role弥合语义断层 - 避免对
<section></section>或<article></article>随意加role="region":它会生成额外地标,导致屏幕阅读器用户听到一堆“区域 1、区域 2…”而无法判断用途 -
<nav aria-label="主导航"></nav>:用于顶部横向菜单 -
<nav aria-label="页脚链接"></nav>:放在<footer></footer>内的链接集合 -
<nav aria-label="搜索建议"></nav>:仅当搜索框展开后动态渲染的建议列表才适用 - 给每个
<section></section>都加role="region":制造大量空泛地标,破坏导航效率 - 用
<div role="region"> 包裹广告位却不加 label:屏幕阅读器只报“区域”,用户不知道这是广告还是内容 <p>正确做法:</p> <ul> <li>仅对功能明确但无原生标签的区块使用,例如实时通知弹窗、多步骤表单的状态面板</li> <li>必须提供具体、简短的 <code>aria-label,如aria-label="订单状态更新" - 避免嵌套多个
role="region":优先用<aside></aside>、<section></section>等已有语义的标签 - 多个
<main></main>:屏幕阅读器可能只识别第一个,或报错、行为不可预测 - 把
<main></main>嵌套在<article></article>或<section></section>内:破坏层级逻辑,role="main"被降级为普通内容 - 用
<div role="main"> 替代 <code><main></main>:绕过浏览器内置校验,但失去语义一致性,且部分旧辅助技术不识别检查方法:用浏览器开发者工具打开可访问性树(Accessibility Inspector),确认
role="main"节点是否唯一、是否包裹全部主体内容、是否未被其他地标角色包裹。真正难的不是加
role,而是判断哪里不该加——删掉多余的role,比堆砌更多属性更能提升可访问性。
多个 <nav></nav> 怎么区分?
一个页面可以有多个导航区域(主导航、页脚链接、侧边栏工具栏),但所有 <nav></nav> 默认都算 role="navigation",屏幕阅读器无法分辨哪个是主菜单、哪个是辅助链接。
解决方案是用 aria-label 提供唯一上下文:
注意:aria-labelledby 也可用,但需确保引用的 ID 存在且文本有意义;aria-label 更直接、更可控。
role="region" 什么时候该用?
role="region" 是兜底角色,只在既没有合适 HTML5 标签、又确实需要被识别为独立导航目标时才用。它本身不带语义,必须配 aria-label 或 aria-labelledby,否则对用户毫无意义。
典型误用:
为什么 <main></main> 只能有一个?
<main></main> 对应 role="main",是页面中唯一的核心内容容器。辅助技术依赖它快速跳转到主要内容,跳过头部、导航等重复结构。
违反“唯一性”会导致严重可访问性问题:











