inert 属性不能直接让按钮“失效”,因为它作用于整个元素及其子树,使交互完全不可见,而非仅禁用按钮;正确做法是给弹窗外的页面主体(如 body)添加 inert,而非单独设置按钮。

inert 属性为什么不能直接让按钮“失效”
inert 的作用不是禁用按钮,而是让整个元素及其子树对交互(点击、聚焦、键盘导航、屏幕阅读器)完全“不可见”。它不触发 disabled 行为,也不影响表单提交逻辑——只是浏览器层面忽略它。所以如果你只给弹窗底部的按钮加 inert,它们确实点不动,但问题常出在:你可能误以为要给每个按钮单独加,其实更合理的是把整个遮罩层或主内容区设为 inert。
正确做法:给弹窗外的页面主体加 inert
弹窗出现时,真正需要“暂时失效”的是背后可点击的全部交互区域,不是零散按钮。手动遍历所有按钮并加 inert 容易漏、难维护,且破坏语义结构。推荐方案是:在弹窗打开时,给 或主容器元素动态添加 inert 属性,同时确保弹窗自身不继承该属性(因为它必须可操作)。
- 用
document.body.setAttribute('inert', '')启用遮罩 - 弹窗元素(如
<dialog></dialog>或自定义<div class="modal">)必须显式移除 <code>inert,或放在body外(比如用createPortal或document.body.appendChild),否则它也会被锁死 - 注意:若使用
<dialog></dialog>,现代浏览器已默认模态行为(含自动 inert 背景),无需手动加 —— 但老版本 Chrome/Safari 不支持,得降级处理 - 简单 fallback:打开弹窗时,给
body加class="is-modal-open",再用 CSS 锁住背景:.is-modal-open *:not(.modal) { pointer-events: none; } - 但这样无法阻止键盘焦点进入,需额外用
document.activeElement.blur()+focusin事件拦截 - polyfill(如 WICG/inert)会模拟行为,但会增加 DOM 遍历开销,慎用于高频弹窗场景
- 不要给 inert 元素再加
aria-hidden - 如果用了
aria-modal="true"(比如在<div role="dialog"> 上),必须配合 <code>inert或等效逻辑,否则屏幕阅读器仍能读取背景内容 - 测试时用键盘 Tab 切换 + VoiceOver/NVDA,确认焦点不会落到 inert 区域内 实际生效的关键不在按钮本身,而在你控制的是哪一层 DOM。inert 是“区域开关”,不是“按钮胶带”。漏掉父容器、没处理焦点逃逸、忽略 polyfill 覆盖率,这三点最容易导致看似加了却依然能点。
兼容性与 fallback 必须考虑
inert 在 Safari 16.4+ 和 Chrome 88+ 原生支持,Firefox 仍需 inert-polyfill。如果项目需支持旧版 Safari 或 Firefox,仅靠 inert 会失效。
常见踩坑:inert 和 aria-hidden 混用
有人会同时加 inert 和 aria-hidden="true",这是冗余甚至有害的。inert 已隐含对辅助技术的屏蔽,aria-hidden="true" 却只影响 ARIA 树,不阻止键盘焦点——反而可能导致焦点“卡住”在不可见元素上。











