aria-modal="true"是WAI-ARIA强制要求的属性,必须加在role="dialog"或role="alertdialog"的弹窗最外层容器上,配合aria-labelledby和tabindex="-1",声明该弹窗为模态状态、背景内容逻辑隔离;单独使用无效,须同步管理焦点与aria-hidden。

aria-modal 是什么,什么时候必须加
aria-modal="true" 告诉屏幕阅读器:这个弹窗是模态的,页面其他内容暂时不可访问。它不是装饰性属性——只有当弹窗真正阻断背景交互(比如点击背景不关闭、Tab 键无法跳到背后元素)时才该设为 true。如果弹窗只是视觉浮层但背景仍可操作,加了反而误导辅助技术。
怎么给弹窗元素正确设置 aria-modal
必须直接加在弹窗最外层容器上,且该容器需同时满足语义和可聚焦条件:
- 用
role="dialog"或role="alertdialog"显式声明角色 - 必须有
aria-labelledby指向标题元素(不能只靠视觉文本) - 容器本身要能获得焦点,推荐加
tabindex="-1" -
aria-modal="true"不能写在 body 或遮罩层上,只作用于对话框主体
示例:
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title" tabindex="-1"> <h2 id="dialog-title">确认删除?</h2> <p>此操作不可撤销</p> <button>取消</button> <button>确定</button> </div>
不加 aria-modal 会出什么问题
屏幕阅读器(如 NVDA、VoiceOver)可能继续朗读背景内容,用户无法感知当前处于模态流程中;键盘 Tab 键仍能落到弹窗外的按钮或链接上,破坏“模态”预期;部分浏览器+读屏组合会忽略 aria-hidden="true" 对背景的隐藏效果。
立即学习“前端免费学习笔记(深入)”;
常见错误现象:
- 弹窗打开后,按 Tab 键跳到页脚导航栏
- 用 VoiceOver 手势滑动时,突然读出顶部 banner 文本
- NVDA 报告“已离开对话框”,但实际焦点还在弹窗内
配套必须做的几件事
aria-modal="true" 单独存在没用,必须配合以下操作:
- 弹窗显示时,给
<body>加aria-hidden="true"(同时记得移除 tabindex) - 确保弹窗内至少有一个可聚焦元素,并在打开时自动
.focus()到它(通常是第一个button或标题) - 关闭弹窗后,焦点必须回到触发它的元素(别留在 body 上)
- 避免用
display: none控制弹窗显隐——它会让辅助技术完全忽略该节点,应改用visibility: hidden+aria-hidden="true"
容易被忽略的是焦点管理:很多 JS 弹窗库只管 show/hide,不处理 focus 回溯,结果导致键盘用户卡死在空白处。



















