不能用 aria-colcount 和 aria-rowcount 标注虚拟滚动表格的总行列数,因规范要求其值必须等于当前渲染的行列数,设为总数会误导屏幕阅读器、触发警告或导航失效。

不能用 aria-colcount 和 aria-rowcount 标注虚拟滚动表格的总行列数——这是规范禁止、实测失效、且会破坏屏幕阅读器导航的行为。
为什么设成总数会导致屏幕阅读器出错
这两个属性在 WAI-ARIA 规范中明确定义为“当前渲染区域的行列数量”,不是数据集逻辑尺寸。设 aria-rowcount="10000" 给只渲染 20 行的容器,等于向辅助技术撒谎:
- NVDA + Firefox 会忽略该值,或对超大数字(如
1e6)直接跳过网格导航 - JAWS 检测到 DOM 节点数远小于
aria-rowcount,触发“表格不一致”警告,降级为普通列表处理 - VoiceOver 在移动端不支持动态更新,设错会导致首屏焦点丢失、无法进入网格
虚拟滚动表格该用哪些 ARIA 属性
核心思路是:让屏幕阅读器感知“这是一个可滚动的、有明确范围的网格”,而不是假装它是个完整表格。
- 容器必须设
role="grid"(不是<table>),声明语义为交互式网格 <li> <code>aria-rowcount和aria-colcount必须严格等于当前实际渲染的行数和列数(例如渲染 15 行 × 8 列,就写aria-rowcount="15"、aria-colcount="8") - 每个单元格需带
aria-rowindex(从 1 开始)和aria-colindex,值对应其在全量数据中的逻辑位置(如第 3201 行第 4 列,就写aria-rowindex="3201" aria-colindex="4") - 必须通过
aria-describedby指向一个说明性元素,例如:<div id="grid-desc">数据表格,共 9842 行,使用方向键或 Page Up/Down 浏览</div><div role="grid" aria-describedby="grid-desc"></div>
- 每次滚动后,必须重设容器的
aria-rowcount和aria-colcount—— 不是全量总数,而是当前渲染块的尺寸 - 每个新挂载的
<div role="row"> 子元素,要补上 <code>aria-rowindex="{逻辑行号}"(比如加载的是第 4721 行数据,就写aria-rowindex="4721") - 页码或范围提示(如“显示第 4721–4740 行”)建议用
aria-live="polite"包裹,确保变更后能被播报
滚动时最容易漏掉的同步动作
虚拟滚动靠 JS 动态替换 DOM,ARIA 属性不同步就会让屏幕阅读器“迷路”:
真正影响滚动体验的,不是 aria-rowcount 的数值,而是 role="grid" + 键盘导航逻辑 + 动态 ARIA 同步这三者的闭环。漏掉任意一环,用户就可能卡在空白区域或重复播报同一行。











