原生html5地标标签(如、)已自带正确aria role,显式添加role不仅不必要,还易引发landmark-is-unique等可访问性错误;应优先使用语义化结构、明确命名,并通过chrome devtools accessibility inspector验证computed role、name和states。

直接用 <header></header>、<nav></nav>、<main></main>、<aside></aside>、<footer></footer> 这些原生标签,就已满足绝大多数地标角色需求;显式加 role 不仅不必要,反而容易触发 landmark-is-unique、landmark-no-label 等可访问性错误。
Chrome DevTools Accessibility Inspector 怎么快速验证地标是否生效
不用装插件、不跑 CLI,Chrome 自带的 Accessibility Inspector 就能实时看地标是否被正确识别。打开方式:Mac 按 Cmd+Shift+P,Win/Linux 按 Ctrl+Shift+P,输入 “Accessibility” 回车;或右键任意元素 → Inspect Accessibility Properties。
重点盯三列:
-
Computed Role:它实际被辅助技术当成什么(比如<nav></nav>应显示navigation,若显示generic,说明被display: none或visibility: hidden隐藏了) -
Name:屏幕阅读器读出的名称(为空即触发landmark-no-label) -
States:如expanded、hidden是否同步(尤其对role="search"或role="region"类容器)
为什么给 <nav></nav> 加 role="navigation" 反而报错
HTML5 原生标签自带隐式 ARIA role:<nav></nav> 默认就是 role="navigation",<main></main> 默认是 role="main",<footer></footer> 是 role="contentinfo"。W3C 明确要求“不要改写原生语义”,除非你在 polyfill 旧浏览器。
常见错误现象:
- 多个
<nav></nav>元素都未加aria-label或aria-labelledby→ 全被读成“导航区域”,用户无法区分主导航、面包屑、页脚链接 - 用
<div role="main"> 替代 <code><main></main>→ 可以,但必须确保全局唯一,重复会触发landmark-is-unique - 给
<section></section>加role="region"却没配aria-label→ 直接报landmark-no-label - 保持原生表格结构,在每个
<input type="search">上加aria-label="按姓名筛选" - 避免用
aria-labelledby指向表头文字复用名称 —— 筛选控件和表头语义不同,用户需要明确知道“这是筛选框”,不是“这是列名” - 用
<input type="search">,它已自带role="searchbox"和基础无障碍支持 - 必须包裹在
<form></form>中(哪怕 JS 拦截提交) - 必须设
name="q"(行业惯例,后端和 SEO 友好) - 必须用
aria-label或aria-labelledby提供名称 ——placeholder不能替代 - 若需独立地标语义,用
<section role="search"></section>包一层,再把<input type="search">放进去
表格里加筛选行时,role="search" 为什么总报 aria-requires-children
这不是你漏写了子元素,而是你把 role="search" 错加在了 <tr> 上。HTML 中 <code><tr> 的隐式 role 是 <code>row,<th> 是 <code>columnheader,<td> 是 <code>cell。一旦给 <tr> 加 <code>role="search",它就不再是表格行,而变成一个独立的 landmark,导致其父 <thead> 下出现非法子元素(<code>search 不在 <thead> 允许的子元素列表里)。
<p>修复方法极其简单:</p>
<ul><li>删掉所有加在 <code><tr>、<code><th>、<code><td> 上的 <code>role 声明 —— 它们全是多余的,且有害
<input type="search"> 为什么不能加 role="search"
role="search" 是给整个搜索区域(比如包含输入框、按钮、筛选项的 <section></section> 或 <div>)用的,不是给 <code><input> 本人加的。强行加在 <input> 上,会覆盖它原本由 type="search" 自动提供的 role="searchbox",导致屏幕阅读器误读为“一个叫 search 的容器”,而不是“一个可输入的搜索框”。
正确做法是:
最易被忽略的是:地标角色不是靠堆 role 实现的,而是靠结构清晰 + 名称明确 + 原生语义优先。一旦开始手动加 role,就得同步处理焦点、键盘事件、状态同步和屏幕阅读器反馈 —— 否则只是贴了一张失效的标签。











