aria-selected="true"仅在role="tablist"/"grid"/"tree"等复合角色上下文中有效,需JS同步更新属性与样式,并显式设置所有非选中项为aria-selected="false"。

aria-selected="true" 必须配合 role="tablist" / "grid" / "tree" 等复合角色使用
单独给任意元素加 aria-selected="true" 不会触发屏幕阅读器播报“已选中”,也不会被 AT(辅助技术)识别为有效状态。它只在特定 WAI-ARIA 复合组件上下文中才有语义意义。
常见误用:给普通 无障碍要求的是状态同步:视觉变化(如高亮)和 ARIA 状态必须严格一致。仅切换 正确做法是用 JS 同时操作 DOM 属性和样式: 实现 Markdown↔ HTML 互转,支持导出 PDF,用于用户请求的文档格式转换。 框架组件化渲染时,常因条件渲染或 key 变化导致 错误写法(只设选中项,未设其他项为 false): 正确写法(显式控制每个项):
实际项目中最容易被跳过的,是「所有非选中项都必须明确设为 直接加 aria-selected,却不设 role —— 这属于无效标注,AT 会忽略该属性。
role="tablist" + aria-selected 用于标签页(tabs),每个 tab 应有 role="tab"
role="grid" + aria-selected 用于可选中表格(如数据表格行选中),子项需为 role="row" 和 role="gridcell"
role="tree" + aria-selected 用于树形控件,节点需为 role="treeitem"
选中态必须由 JS 动态控制,不能仅靠 CSS 类切换
.is-selected 类但不更新 aria-selected,会导致屏幕阅读器读取错误状态。tabEl.setAttribute('aria-selected', 'true');
tabEl.classList.add('tab--selected');
// 切换前务必清除旧选中项
oldTabEl.setAttribute('aria-selected', 'false');
oldTabEl.classList.remove('tab--selected');
aria-selected 做纯样式钩子(例如 CSS 中写 [aria-selected="true"] { background: #007bff; } 是 OK 的,但前提是 JS 确实同步设置了该属性)aria-selected 替代原生 checked 或 selected —— 单选/复选框、 应优先用原生语义键盘焦点与 aria-selected 必须分离管理
aria-selected="true" 描述的是“逻辑选中”,不是“当前聚焦”。用户用 Tab 键移动焦点时,焦点可能落在未选中的项上;按方向键切换选中项时,焦点也未必跟随移动 —— 这两者是正交的。
tabindex、focus())决定键盘操作目标aria-selected 决定“哪个项被用户视为当前激活/选定”role="tablist" 中,应保持一个 tab 永远有焦点(用 tabindex="0"),而 aria-selected="true" 只出现在当前激活的 tab 上,二者可不同步(例如按 ←→ 切换选中态但不移焦)React/Vue 中容易漏掉 aria-selected 的条件重置
aria-selected 属性残留或丢失。比如用 v-for 或 {items.map()} 渲染 tab 列表,但没在每次 render 时显式设置所有项的 aria-selected 值。{tabs.map(tab => (
<button role="tab" activeid :>
{tab.label}
</button>
))}
{tabs.map(tab => (
<button role="tab" aria-selected="{tab.id" activeid : tabindex="{tab.id">
{tab.label}
</button>
))}
aria-selected 也必须准确,不能依赖 JS 注入后才补全aria-selected 是否实时存在且值正确aria-selected="false"」—— 很多人只记得设 true,却让其他项留空,而空值 ≠ false,AT 会将其视为“未定义状态”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










