inert 属性本身不阻止文本选中,但会间接导致无法选中;它使元素退出可访问性树、失去焦点、阻断事件冒泡,却不修改 css 或拦截 js 主动选中,需配合 user-select: none 等样式才能可靠禁用选中。

inert 属性本身不阻止文本选中,但会间接导致无法选中
inert 的核心作用是让元素及其子树退出可访问性树、失去焦点能力、阻断事件冒泡——它并不直接控制 user-select 或文本选择行为。但因为 inert 元素内所有子节点(包括 p、span、div)都不再参与交互链路,浏览器在渲染时会跳过该子树的“可选中”状态计算。结果就是:用户双击或拖选时,光标不会变成文本选择态,document.getSelection().toString() 也拿不到其中内容。
为什么不能依赖 inert 来“禁止选中”
inert 不是样式控制开关,它不修改 CSS 渲染属性。如果页面里有 user-select: all 或 -webkit-user-select: text 这类显式声明,且浏览器未完全执行 inert 隔离(比如 Safari 17.x 或旧 Edge),部分文字仍可能被意外选中。更关键的是:JS 仍可通过 element.select() 或 Range API 主动选中 inert 区域内的文本——inert 不拦截这些主动调用。
- inert 对
document.execCommand('selectAll')无防护力 - 移动端长按触发的系统级文本选择菜单,在某些 Safari 版本中可能短暂绕过 inert 状态
- 若 inert 元素内嵌了
<input>或<textarea></textarea>,它们本身有独立 selection API,inert 只阻止聚焦,不封禁input.setSelectionRange()
真正要禁用选中,得配 CSS + inert 双保险
只靠 inert 不够稳妥。必须叠加 CSS 规则才能覆盖所有路径:
- 给 inert 容器加
user-select: none(含-webkit-user-select、-moz-user-select) - 避免在 inert 区域内使用
contenteditable="true"—— 这类元素即使 inert,也可能因编辑上下文残留 selection 行为 - 不要用
pointer-events: none替代 inert:它不影响键盘导航,也无法阻止 Tab 进入后手动双击选中文本
示例写法:
<div inert style="user-select: none; -webkit-user-select: none;"><p>这段文字既不可聚焦、不可点击,也无法被鼠标或触摸选中</p></div>
服务端渲染时 inert 和 user-select 的顺序很重要
SSR 框架(如 Astro、Next)输出 HTML 时,若只写 <div inert> 而没带内联 <code>style,客户端 hydration 后 JS 设置 el.inert = true 会生效,但 CSS 是异步加载或延迟应用的——这中间存在时间窗口,用户可能完成选中操作。所以最稳的方式是:服务端就输出带 style 的 inert 元素,确保首屏即隔离。
另外注意:Safari ≤17.4 不支持 inert,此时全靠 CSS user-select: none 和手动遍历设置 tabIndex = -1 + pointer-events: none,但这些补丁无法阻止 JS 主动调用 select(),复杂场景下得加 onselectstart 事件监听并 return false。











