inert 是浏览器原生的交互与可访问性隔离机制,Chrome 111+、Firefox 121+、Safari 18.0+ 支持,旧版需手动兜底;仅作布尔属性使用,JS 必须用 .inert = true/false 控制,不可用 setAttribute。

inert 属性不是“加个 class 或样式就能禁用”的替代方案,它是一套浏览器原生的交互与可访问性隔离机制——只在 Chrome 111+、Firefox 121+、Safari 18.0+ 中真正生效,旧版浏览器完全无视,且无法靠 CSS 或 JS 事件拦截完整模拟。
直接写 HTML 时怎么用 inert
最简方式就是把 inert 当作布尔属性写在任意元素上,不带值:
<main inert> <p>这段文字不可点击、不可选中、不可聚焦,屏幕阅读器也读不到</p> <button>按钮也被锁死</button> </main>
-
inert没有值,不要写成inert=""或inert="true";写了属性名就生效,删掉就恢复 - DOM 解析后立即切断该元素及其所有子节点的交互链路和可访问性树挂载
- 不影响布局、不隐藏内容、不改变样式——它只管“存在性”,不管“可见性”
JS 动态控制 inert 必须用 .inert = true/false
不能用 setAttribute('inert', ''),也不能用 removeAttribute('inert')——这些操作对 inert 完全无效。
- 正确写法:
el.inert = true立即退出焦点(如果当前聚焦其中)、阻止所有事件冒泡进子树、移出可访问性树 -
el.inert = false恢复全部交互能力,包括重新参与 tab 顺序 - React/Vue 中若 SSR 或 hydration 时没同步
inert状态,会触发 “prop mismatch” 警告
为什么不用 pointer-events: none + aria-hidden 组合
这种组合看似能覆盖鼠标、视觉、读屏,但实际漏掉关键路径:
立即学习“前端免费学习笔记(深入)”;
-
pointer-events: none不影响键盘导航:Tab 仍能聚焦到<input>或<button></button>,焦点卡住后无法自然离开 -
aria-hidden="true"只隐藏给读屏器,不影响键盘操作,也不阻止鼠标事件冒泡 - 两者叠加后,用户可能用键盘触发表单提交、意外激活隐藏按钮、或被辅助技术报出“可聚焦但不可用”的矛盾状态
-
inert是唯一同时切断鼠标、键盘、AT(辅助技术)三端信号的原生方案
兼容性兜底必须手动做,没有 magic polyfill
在不支持 inert 的浏览器里(比如 Safari 17 或旧 Edge),只能退回到“半禁用”策略,且需逐层处理:
- 遍历所有可聚焦元素(
button、a[href]、input、[tabindex]等),统一设tabindex="-1"并移除 focus 监听 - 对容器加
pointer-events: none防鼠标,再配aria-disabled="true"提供语义提示 - 浮动层(如 toast、loading)必须放在
inert容器外层 DOM,否则一并被锁死 - 使用 WICG/inert polyfill 时,新插入的
[inert]节点需手动调用inert.apply(),polyfill 不监听 DOM 变化
inert 不是样式控制,也不是事件拦截开关,它是 DOM 层级的“存在性开关”——一旦启用,整个子树在浏览器交互模型和可访问性树中就“不存在”了。



















