chrome devtools 的 accessibility inspector 可实时验证地标角色,检查 computed role、name 和 states 三列,识别 role 缺失、冗余或语义冲突,并提示如 landmark-no-label、landmark-is-unique 等问题。

Chrome DevTools 能直接揪出地标角色缺失或错配
不用装插件、不跑 CLI,Chrome 自带的 Accessibility Inspector 就能实时验证 role 是否生效、是否被覆盖、是否与 HTML 语义冲突。打开方式很简单:Mac 按 Cmd+Shift+P,Win/Linux 按 Ctrl+Shift+P,输入 “Accessibility” 回车;或者右键任意元素 → Inspect Accessibility Properties。
重点盯三列:Computed Role(它实际被当成什么)、Name(屏幕阅读器读出的名称)、States(比如 expanded 或 hidden 是否同步)。如果 nav 元素的 Computed Role 显示为 generic,基本就是被 CSS 隐藏了(display: none 或 visibility: hidden),或 JS 移除了,可访问性树里根本没它。
-
header、main、nav、aside、footer这些原生标签默认有对应地标 role,但若加了role="banner"之类冗余声明,反而可能触发警告——W3C 明确要求“不要改写原生语义”,除非你真在 polyfill 旧浏览器 -
role="navigation"必须配aria-label或aria-labelledby,否则多个nav元素全被读成“导航区域”,用户无法区分主导航、面包屑、页脚链接 - 用
div role="main"替代原生main标签?可以,但必须确保全局唯一——W3C 规范只允许一个main地标,重复会触发landmark-is-unique错误
为什么 role="search" 常在表格里报 aria-requires-children
这不是你漏写了子元素,而是你强行把 tr 改成了 role="search",彻底破坏了表格结构。HTML 中 tr 的隐式 role 就是 row,th 是 columnheader,td 是 cell。一旦给 tr 加 role="search",它就不再是表格行,而变成一个独立的 landmark,导致其父 thead 下出现非法子元素(search 不在 thead 允许的子元素列表里)。
- 修复方法极其简单:删掉所有
role="search"、role="row"、role="columnheader"—— 它们全是多余的,且有害 - 筛选行保留原生
tr+td结构,在每个input type="search"上加aria-label="筛选姓名列"即可 - 别用
aria-labelledby指向表头文字来复用名称——筛选控件和表头语义不同,用户需要明确知道“这是筛选框”,不是“这是列名”
检测工具报 landmark-no-label 怎么快速定位
这个错误意思是“地标元素没有可访问名称”,比如 nav、section role="region"、aside 等缺少 aria-label 或 aria-labelledby。它不像语法错误那样有行号提示,得靠 DevTools 逐个点开看 Name 列是否为空或为 “(empty)”。
- 常见高危位置:
nav(尤其多处出现时)、自定义弹窗容器(div role="dialog")、侧边栏aside、底部工具栏footer(若含交互功能) - 优先用
aria-label:简洁可控,比如nav aria-label="主导航"、aside aria-label="用户快捷操作" - 避免
aria-label="Navigation"这类泛化文案——英文界面统一用"Main navigation",中文用"主导航",不拼写变体 - 如果地标内已有可见标题(如
<h2 id="filter-title">筛选条件</h2>),可用aria-labelledby="filter-title",但注意该标题必须在 DOM 中真实存在且未被aria-hidden="true"掩盖
Trae CLI 扫描能发现哪些静态地标问题
Trae 的 @trae/plugin-a11y 插件基于 axe-core,对地标类缺陷做静态分析时,主要覆盖两类:一是缺失必填 ARIA 名称(landmark-no-label),二是错误覆盖原生语义(aria-allowed-attr 检查中会标记 role="search" 在 tr 上的使用)。
- 运行
trae check --a11y后,报告里会明确标出文件路径、行号、错误类型,例如:src/pages/list.html:42:5 - landmark-no-label: <nav> element does not have a label</nav> - 它不会检测动态插入的地标(比如 JS 创建的
div role="alert"),这类必须走trae serve启服务后进浏览器面板手动 Run Analysis - CI 流程中设
TRAE_A11Y_THRESHOLD=0可强制阻断构建,但要注意:某些第三方组件库生成的地标(如 React Router 的nav)可能无aria-label,需用/* trae-disable a11y/landmark-no-label */注释临时屏蔽,而非妥协语义
真正难的不是加属性,是判断“这里到底需不需要加”。很多 role 和 aria-label 是开发者凭感觉补的,结果掩盖了结构缺陷——比如用 div role="navigation" 包一堆链接,却不重构为语义化 nav;或者给整个表格加 role="grid",却忘了 grid 要求严格管理焦点和键盘行为。这些都不是检测工具能自动修的。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











