inert是唯一原生支持同时禁用交互、聚焦和辅助技术访问的HTML布尔属性,必须写为或JS赋值el.inert = true,不支持setAttribute或字符串值,旧浏览器需手动兜底。

inert 是目前唯一能真正让任意 HTML 元素及其子树完全不可交互、不可聚焦、不可被屏幕阅读器访问的原生方案。 它不是 CSS 技巧,也不是事件拦截补丁,而是浏览器直接“忽略该 DOM 子树存在”的语义级开关。但用错方式、忽略兼容性或混搭旧方案,反而会让键盘用户卡死、读屏器报错、甚至触发 hydration mismatch。
怎么写 inert 属性才生效
inert 是布尔属性,只认有无,不认值。写成 inert="" 或 inert="true" 是无效的——浏览器会解析为字符串值,而非布尔真值,实际不生效。
- ✅ 正确写法:
内容
- ❌ 错误写法:
、...... - ⚠️ 注意:服务端渲染(SSR)或框架 hydration 时,初始 HTML 必须带
inert属性;若 JS 后续才赋值el.inert = true,React/Vue 会报 “prop mismatch” 警告
JS 动态控制 inert 必须用 .inert = true/false
DOM API 中只有 element.inert 这个属性可写,且是同步生效的。所有基于 attribute 的操作对 inert 都无效。
- ✅ 正确:
el.inert = true(立刻失焦、阻断事件、退出可访问性树) - ❌ 无效:
el.setAttribute('inert', '')、el.removeAttribute('inert')、el.toggleAttribute('inert') - ? 小技巧:设
el.inert = false后,元素会重新参与 tab 顺序,但不会自动恢复焦点——需手动el.focus()(如果逻辑需要)
为什么 pointer-events: none + aria-hidden 不够用
这种组合看似覆盖全面,实则在键盘导航和辅助技术路径上存在致命缺口。
- ?️
pointer-events: none不影响Tab导航:按钮仍可被聚焦,焦点卡住后无法自然离开 - ?️
aria-hidden="true"只隐藏给读屏器,不阻止键盘事件,也不禁用鼠标事件冒泡 - ? 混搭后常见问题:用户按回车意外提交表单、读屏器播报“可聚焦但不可操作”、测试工具报 ARIA 矛盾
- ✅ inert 是唯一同时切断鼠标、键盘、AT(辅助技术)三端信号的原生机制
不支持 inert 的浏览器(如 Safari ≤17)怎么兜底
没有 magic polyfill。Chrome Inert Polyfill 是最接近的实现,但它靠遍历+模拟,无法 100% 复现原生行为,尤其在虚拟键盘、焦点管理、Shadow DOM 场景下易出错。
- ? 手动降级策略必须逐层处理:
– 查找所有可聚焦元素(button、a[href]、input、[tabindex]等)
– 统一设tabindex="-1"并移除focus监听
– 容器加pointer-events: none+aria-disabled="true"提供语义 - ⚠️ 特别注意:浮动层(toast、loading、tooltip)必须放在
inert容器外层 DOM,否则会被一并锁死 - ? 最容易被忽略的一点:
inert不是样式或事件开关,它是 DOM 层级的“存在性开关”——启用后,那个子树在浏览器交互模型和可访问性树中,就真的相当于不存在。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











