inert属性是浏览器原生的交互与可访问性隔离机制,使元素及其子树完全不可聚焦、不可点击、不响应事件且不参与可访问性树;必须写为布尔属性(如),js控制须用el.inert = true/false,不支持setattribute,旧浏览器需手动降级。

inert 属性不是“让按钮变灰”,而是让浏览器彻底忽略那一块 DOM 子树的交互存在性——点不了、Tab 不进去、屏幕阅读器读不到、拖拽进不去、甚至 document.elementFromPoint() 都返回 null。
inert 必须写成布尔属性,不能带值
HTML 中直接写 inert 就生效,不加任何值:
<main inert><button>这个按钮完全不可用</button> <input type="text"></main>
以下写法全部无效:
-
inert=""或inert="true"—— 浏览器解析后不触发行为 -
setAttribute('inert', '')—— DOM 属性存在,但inert逻辑不响应 -
el.toggleAttribute('inert')—— 同样被忽略,仅操作 attribute 层面
真正起效的只有:元素节点上存在该布尔属性(HTML 写法),或 JS 赋值 el.inert = true。
JS 动态控制必须用 .inert = true/false
动态开关时,.inert 是可读写的 DOM 属性,赋值即刻生效:
-
mainContent.inert = isModalOpen—— 焦点自动退出、事件不再冒泡、AT 树实时更新 - 设为
false后,原tabindex和聚焦顺序立即恢复 - 若用 React/Vue,SSR 渲染的 HTML 必须初始含
inert(如<main inert></main>),否则 hydration 会报 “prop mismatch”
常见错误是混用 class 控制(如 class="is-inert" + CSS pointer-events: none),这只能拦鼠标,拦不住 Tab 进入 <input> 或读屏器播报。
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
DOM 结构错位会导致浮层一并失活
弹窗、toast、loading 蒙层必须和 inert 区域是兄弟节点,不能嵌套在其中:
<div id="app"> <main inert id="main-content"></main><dialog open></dialog><div class="toast"></div> </div>
如果把 <dialog></dialog> 放进 <main></main> 里,它也会被锁死——关闭按钮点不动、Tab 键跳不进去、屏幕阅读器读不到标题。更糟的是,给 加 inert 会让所有全局监听器(如 document.addEventListener('keydown', ...))失效,ESC 关闭逻辑直接瘫痪。
旧浏览器兜底不是“加个 polyfill 就完事”
WICG/inert polyfill(如 @webcomponents/inert)只模拟部分行为:
- 支持 Safari 10+,但不处理辅助技术语义——屏幕阅读器仍可能读取内容
- 动态插入的新
[inert]元素(如 Vue 组件重渲染后挂载)polyfill 不自动接管,需手动调用inert.apply(el) - IE11 中
Element.focus()主动调用会失败,且无法修复
真正兼容的降级策略是三件套同步做:aria-hidden="true" + tabIndex = -1(父容器)+ pointer-events: none,再递归禁用所有可聚焦子元素(button、a[href]、input、[tabindex] 等),缺一不可。
最容易被忽略的一点:inert 不影响滚动行为本身,但如果滚动容器是 <main></main> 自身,加 inert 后用户仍可滚;而如果靠 滚动,又没注意 body 是否被意外冻结,就会出现“内容卡住但滚动条还在”的诡异现象。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










