role="progressbar" 必须配合 aria-valuenow 和 aria-valuemin/aria-valuemax 才能被屏幕阅读器正确播报,仅设 role 无效;需显式提供数值范围与当前值,不确定进度时应改用 role="status" 或 aria-busy="true"。

role="progressbar" 必须配合 aria-valuenow 和 aria-valuemin/aria-valuemax
只写 role="progressbar" 不会触发屏幕阅读器播报,它只是个语义占位符。必须提供当前值和范围,否则辅助技术无法读出进度状态。
-
aria-valuenow是必需的动态值(比如 65),不能是字符串或空值 -
aria-valuemin默认为 0,但显式写上更稳妥;aria-valuemax必须明确(比如 100) - 如果进度是不确定的(如“加载中”),改用
role="status"或aria-busy="true",别硬套 progressbar
视觉样式要独立控制,role 不影响外观
role="progressbar" 不带任何默认样式,CSS 需手动实现进度条视觉效果。常见错误是以为加了 role 就自动有动画或填充效果。
- 推荐用
<div>+role="progressbar",再通过width或transform: scaleX()控制填充比例 - 避免用
<progress>元素再额外加role="progressbar"—— 它原生已有该 role,重复会导致冗余或冲突 - 若用 CSS 动画模拟进度,确保
aria-valuenow同步更新,否则语音播报和实际视觉不同步
键盘交互不是自动附带的,需手动支持
原生 <progress> 不可聚焦也不响应键盘操作,而自定义 role="progressbar" 更不会自动获得焦点或方向键支持。
- 必须添加
tabindex="0"才能让它被键盘聚焦 - 如需支持方向键调整(比如开发调试工具),要监听
ArrowLeft/ArrowRight并更新aria-valuenow - 多数场景下进度条是只读状态,此时不建议加键盘交互,反而增加认知负担
与 aria-labelledby / aria-describedby 配合才能完整传达上下文
单独一个 progressbar 很难说明“正在上传文件”还是“安装应用”,必须关联描述性文字。
立即学习“前端免费学习笔记(深入)”;
- 用
aria-labelledby="id1"指向标题元素(如<h3 id="id1">文件上传中</h3>) - 用
aria-describedby="id2"补充细节(如剩余时间、错误提示),ID 对应<div id="id2">还剩 2 分钟</div> - 避免仅靠视觉位置暗示关联 —— 屏幕阅读器不会按 DOM 顺序自动拼接,必须显式声明
容易忽略的是:当进度完成时,aria-valuenow 要设为 aria-valuemax 的值,并考虑是否移除 role 或切换为 role="status" 来宣告完成,而不是让屏幕阅读器继续读“100% 进度条”。



















