aria-rowindex 必须严格用于 role="row" 或 role="gridcell" 元素,显式声明逻辑行号;原生 table 中禁用,仅虚拟表格(div+role="grid")适用;需与 aria-rowcount 严格匹配,且每行/单元格均需正确设置。

aria-rowindex 必须写在 role="row" 或 role="gridcell" 元素上
它不是给
常见错误:<tr aria-rowindex="5"> —— 无效,</tr>
<tr> 是原生语义元素,不参与 ARIA grid 模式;<code><div aria-rowindex="5"> —— 无效,缺少 <code>role="row" 或 role="gridcell",AT 不识别其为“行”。
- 正确写法:用
<div role="row" aria-rowindex="5"> 声明第 5 行 <li>如果该行内有单元格,每个 <code><div role="gridcell" aria-rowindex="5" aria-colindex="1"> 都得带 <code>aria-rowindex,不能只靠父容器继承 - 动态渲染时,哪怕只显示第 49–53 行,
aria-rowindex仍必须是 49、50、51、52、53,不能重置为 1–5 - 跳过中间列(如从 1 直接到 47)完全合法,但数值必须准确,否则 NVDA 会把“第 47 列”读成“第 2 列”
- 不能省略
aria-rowindex只留aria-colindex,否则 screen reader 无法确认这是哪一行的数据 - 同一行多个
gridcell的aria-rowindex值必须一致,否则会被解析为跨行单元格(而你没声明aria-rowspan,这反而造成语义矛盾) - 你用 Vue/React 动态生成
,但表格结构本身是原生的,此时 aria-rowindex仍是多余的- 你用
<div role="grid"> 模拟表格(即所谓“虚拟表格”),这才是 <code>aria-rowindex的唯一合法使用场景简单判断标准:如果外层是
<table>,就别碰 <code>aria-rowindex;如果是<div role="grid">,就必须每行、每个单元格都带它。 <h3>aria-rowcount 和 aria-rowindex 要严格对齐</h3> <p><code>aria-rowcount写在外层role="grid"容器上,代表整个表格的总行数(比如 1000);aria-rowindex写在每个role="row"或gridcell上,代表该行在全部 1000 行中的序号。两者数值范围必须能闭合——如果aria-rowcount="1000",那出现aria-rowindex="1001"就是硬错误。- 分页表格中,
aria-rowcount应为全量数据总行数,不是当前页行数 - 空行(如占位符、加载中提示)如果参与逻辑结构,也要分配
aria-rowindex;如果纯视觉占位且aria-hidden="true",则不应计入aria-rowcount - 用 axe 或 WAVE 扫描时,
aria-rowcount缺失或与实际最大aria-rowindex不匹配,会直接报 ARIA 报错
最易被忽略的一点:当你用 JS 动态插入新行,不仅要生成 DOM,还得同步更新外层的
aria-rowcount值,并给新行分配正确的aria-rowindex——漏掉任一环节,视障用户就会在“第 100 行”之后突然听到“第 1 行”。 - 你用
多列表格中,aria-rowindex 和 aria-colindex 要独立配对,不能靠 DOM 顺序推断
虚拟表格(比如用 div + CSS Grid 实现的横向滚动表格)里,列可能被裁剪或懒加载,视觉上只显示前 3 列,但逻辑上有 50 列——这时 aria-colindex 必须如实反映真实列序(如 aria-colindex="47"),aria-rowindex 同理,且二者组合才能定位唯一单元格。
如果某行只渲染了姓名、邮箱两列,但它们实际对应逻辑第 1 列和第 47 列,你就得写:<div role="gridcell" aria-rowindex="12" aria-colindex="1">张三</div> 和 <div role="gridcell" aria-rowindex="12" aria-colindex="47">zhang@example.com</div>。
原生
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











