inert属性能彻底切断键盘Tab流,必须写为<main inert>且JS用.inert = true/false控制;给<main>加inert比<body>安全,因弹窗需置于其外层;旧浏览器需手动设aria-hidden、tabIndex=-1并劫持焦点。

inert 属性能直接切断键盘 Tab 流,但必须写对位置和方式
inert 不是“让按钮变灰”,而是让浏览器彻底忽略整块 DOM 子树的焦点能力——Tab 键会直接跳过它,focus() 调用无效,当前聚焦其中的元素也会自动失焦。但它只在现代浏览器中生效,且 JS 控制必须用 .inert = true/false,不能靠 setAttribute。
为什么给 <main> 加 inert 比给 <body> 安全
模态框(如 <dialog> 或自定义浮层)必须放在 inert 区域的外层 DOM 中,否则一并被锁死:
- ✅ 正确结构:
<dialog open></dialog><main inert>...</main> - ❌ 错误结构:
<body inert><main>...</main><dialog></dialog></body>—— 弹窗本身也失去焦点和可访问性 - 滚动容器如果是
<main>自身,加inert后仍可滚动;但若依赖<body>滚动,就得确保它没被意外冻结
旧浏览器不支持 inert 时,键盘聚焦怎么兜底
Chrome 111+、Firefox 121+、Safari 18.0+ 原生支持;Safari 17、旧 Edge、多数安卓 WebView 完全不识别 inert,polyfill 也无法 100% 补齐键盘焦点流重定向。检测后必须手动处理:
- 用
if ('inert' in HTMLElement.prototype)判断是否可用 - 不支持时,至少做三件事:
element.setAttribute('aria-hidden', 'true')、element.tabIndex = -1、递归遍历所有可聚焦子元素(button、a[href]、input、[tabindex])并设tabIndex = -1 - 监听
focusin,一旦焦点落入禁用区域,立刻focus()到模态框内首个可聚焦元素 - 别只靠
pointer-events: none——它挡不住 Tab 进入,也拦不住.click()被 JS 主动触发
虚拟键盘弹出时 inert 失效,怎么防卡顿和焦点错乱
移动端调用 VirtualKeyboard API(比如输入框 focus())时,部分浏览器(尤其 Safari 17.x)会短暂忽略 inert 状态,导致焦点卡住或滚动错位:
立即学习“前端免费学习笔记(深入)”;
- 关键点:
inert元素本身不参与布局,但虚拟键盘改变 viewport 高度,可能触发父容器重绘,进而干扰 inert 状态维护 - 临时缓解:在
virtualkeyboardshow和virtualkeyboardhide事件中,手动重置一次inert状态:el.inert = el.inert - 更稳妥的做法:把输入框所在的模态区域也从
inert区域中排除,即只冻结非表单主内容区,而非整个页面主体



















