aria-grabbed 表示元素当前是否正被拖拽,需 javascript 在 dragstart 设为 "true"、dragend 设为 "false",不可静态设置或与 aria-selected 混用。

aria-grabbed 不是“选中”属性,它表示拖拽中的状态
aria-grabbed 是 ARIA 1.1 引入的语义属性,专用于可拖拽(draggable="true")元素,表示该元素当前是否正被用户拖拽中。它和“选中”(如 aria-selected)或“聚焦”(tabindex + focus)完全无关——浏览器不会自动设置它,也不能靠 HTML 静态写死来“选中”。必须由 JavaScript 动态控制。
必须用 JavaScript 手动设置 true/false
浏览器不响应 aria-grabbed="true" 的静态 HTML 值;只有 JS 在拖拽生命周期中显式更新,辅助技术(如屏幕阅读器)才会播报“正在拖拽”。常见配合点:
-
dragstart事件里设element.setAttribute('aria-grabbed', 'true') -
dragend事件里设element.setAttribute('aria-grabbed', 'false') - 注意:不能设为布尔字面量
true/false,必须是字符串"true"或"false" - 若元素支持多选拖拽(如文件列表),需确保每次只对实际被拖的元素设
aria-grabbed="true"
别和 aria-selected、draggable 混用出错
这三个属性职责不同,误配会导致语义混乱:
-
draggable="true"是 HTML 原生属性,开启原生拖拽能力(触发 drag 事件) -
aria-selected="true"表示“被选中”,用于列表、网格等可多选控件(如role="grid") -
aria-grabbed只在dragstart→dragend之间临时为"true",其余时间应移除或设为"false" - 错误示例:
<div draggable="true" aria-selected="true" aria-grabbed="true"> —— 这会让屏幕阅读器同时播报“已选中”和“正在拖拽”,逻辑矛盾 <h3>无障碍测试时容易忽略的细节</h3> <p>即使代码逻辑正确,仍可能因以下原因失效:</p> <ul> <li>未在 <code>dragstart中调用event.dataTransfer.setData(),部分屏幕阅读器不触发aria-grabbed语义播报 - 使用了自定义拖拽库(如 react-dnd、SortableJS),需确认其是否透传或模拟
aria-grabbed更新 - 动态渲染的列表项(如 Vue/React)中,
aria-grabbed状态未随组件重渲染同步,导致旧值残留 - 不要依赖
aria-grabbed控制视觉样式 —— 应用 CSS 类(如.is-dragging)并用 JS 同步增删,避免仅靠属性选择器[aria-grabbed="true"]导致样式延迟或遗漏











