inert 属性是浏览器原生的语义化暂停机制,使元素及其子树完全脱离交互与可访问性树;需现代浏览器支持(Chrome 111+、Firefox 121+、Safari 18.0+),JS 设置须用 element.inert = true,不可用 setAttribute。

inert 属性能真正让元素及其子树“消失”在交互和可访问性树中——不是靠 disabled(只对表单控件有效),也不是靠 pointer-events: none(仍能被键盘聚焦、屏幕阅读器读取),而是浏览器原生的、语义化的暂停机制。
inert 属性生效的前提条件
它只在现代浏览器中可用(Chrome 111+、Firefox 121+、Safari 18.0+),旧版 Safari 和 Edge 旧内核完全不支持,且没有 polyfill 能完美模拟其行为。使用前必须确认目标环境:
-
inert是 HTML 全局属性,可直接写在任意元素上:<div inert>...</div> - JavaScript 中设置需用
element.inert = true(注意:不是setAttribute('inert', ''),后者无效) - 动态添加/移除时,DOM 会立即响应:焦点自动退出 inert 区域,
tabindex失效,click/keydown事件不再冒泡进该子树
inert 和 aria-hidden + pointer-events 的关键区别
很多人试图用组合方式“模拟” inert,但会踩坑:
-
aria-hidden="true"只影响屏幕阅读器,不影响键盘导航或鼠标点击 -
pointer-events: none阻止鼠标,但Tab仍能聚焦其中的input或button,且焦点卡住后无法自然离开 -
display: none或visibility: hidden会破坏布局流或留白,而inert不影响渲染样式,仅切断交互与可访问性链路
真正需要“临时挂起一整块 UI(比如弹窗背后的页面)”时,inert 是唯一能同时解决键盘、鼠标、AT(辅助技术)三端一致性的方案。
立即学习“前端免费学习笔记(深入)”;
常见误用场景与修复建议
最常出问题的是“条件切换”逻辑写错:
- 别在组件挂载时直接设
inert,再等异步结果才移除——这会导致首屏白屏或焦点丢失;应先确保内容可交互,再按需加inert - 不要给
body直接加inert,否则整个页面失活(包括可能存在的 toast、loading 等浮动层);正确做法是给主内容区加inert,把浮层放在其外层 DOM - SSR 渲染时若服务端输出
inert,客户端 hydration 后需同步状态,否则 React/Vue 可能报“prop mismatch”警告
示例:一个模态框开启时禁用背景
<div id="app"> <main inert id="main-content">...</main> <dialog open>...</dialog> </div>
JS 控制逻辑应为:mainContent.inert = isModalOpen,而非操作 class 或 style。
兼容性兜底必须手动做
没 inert 的浏览器里,只能退回到“半禁用”策略:
- 对所有可聚焦元素批量加
tabindex="-1"并移除focus事件监听 - 用
document.addEventListener('focusin', ...)拦截并强制focus()到安全容器 - 配合
pointer-events: none和aria-disabled="true"做视觉与语义提示
这些补丁无法 100% 对齐 inert 行为,尤其是嵌套焦点管理和 AT 支持。所以真实项目中,要么明确要求浏览器版本,要么接受降级体验——别指望靠一行 JS 自动搞定所有环境。



















