inert是浏览器原生交互隔离机制,仅Chrome111+、Firefox121+、Safari18.0+支持;HTML中直接写<element inert>(无值),JS须用el.inert=true/false,不可用setAttribute;它同时禁用鼠标、键盘和辅助技术访问,且不影响渲染样式。

inert 属性不是“加个 class 就能禁用”的开关,它是一套浏览器原生的交互隔离机制——只在 Chrome 111+、Firefox 121+、Safari 18.0+ 中生效,旧版浏览器完全无视,且无法靠 JS 模拟补全。直接写 HTML 或用 JS 控制时,必须严格遵循它的行为边界,否则会触发焦点卡死、读屏混乱或 hydration 警告。
HTML 中直接写 inert 属性怎么用
最简方式就是把 inert 当作布尔属性写在任意元素上,不带值:
<main inert><p>这段文字不可点击、不可选中、不可聚焦,屏幕阅读器也读不到</p></main>
注意三点:
-
inert没有值,不要写成inert=""或inert="true";写了就生效,删了就恢复 - DOM 解析后立即切断该元素及其所有子节点的交互链路和可访问性树挂载
- 它不影响渲染样式:元素仍可见、仍占布局流、文本仍可被“查找”(Ctrl+F)匹配到,但无法选中或复制
JS 动态控制 inert 必须用 .inert = true/false
不能用 setAttribute('inert', ''),也不能用 removeAttribute('inert')——这些操作对 inert 属性完全无效。
浏览器只响应 element.inert 这个 DOM 属性的赋值:
立即学习“前端免费学习笔记(深入)”;
-
el.inert = true:立刻退出焦点(如果当前聚焦其中)、阻止所有事件冒泡进子树、移出可访问性树 -
el.inert = false:恢复全部交互能力,包括重新参与 tab 顺序 - React/Vue 等框架中若服务端渲染(SSR)或 hydration 时没同步
inert状态,会触发 “prop mismatch” 警告,需确保初始 DOM 和 JS 状态一致
为什么不用 pointer-events: none + aria-hidden 组合
这种组合看似能覆盖鼠标、视觉、读屏,但实际漏掉关键路径:
-
pointer-events: none不影响键盘导航:Tab 仍能聚焦到<input>或<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"提供语义提示 - 若使用 WICG/inert polyfill,必须在所有业务脚本之后、且在首次使用
inert属性前加载;动态插入的[inert]节点需手动调用inert.apply(),这点极易忽略
真正难处理的是语义一致性:旧浏览器里你最多做到“看起来不可用”,但无法让辅助技术真正跳过它——inert 的核心价值,恰恰在于它把“不可用”变成了浏览器理解的原生事实,而不是 CSS 或 ARIA 的模拟声明。



















