user-select: none 单独使用在旧版浏览器中无效,必须按顺序写全 -webkit-、-moz-、-ms- 前缀并置标准属性于最后;它不作用于表单控件、伪元素、shadow dom 内部,且移动端需额外加 -webkit-touch-callout: none 抑制长按菜单。

只写 user-select: none 在 Safari ≤16.4、Firefox ≤68、旧版 Chrome/Android WebView 中完全无效——这些浏览器压根不识别标准语法,必须显式声明私有前缀。
为什么 -webkit-user-select 必须放在最前面
浏览器 CSS 解析是顺序覆盖的,且只认自己支持的声明。Safari 15.2 会跳过 user-select: none(不认识),但能识别 -webkit-user-select: none。如果把标准写法写在前面,再被构建工具或手误插进其他规则覆盖,就等于没设防。
-
-webkit-user-select: none覆盖 Safari、iOS、Chrome ≤61、Edge Legacy -
-moz-user-select: none必须加,尤其 Firefox for Android 和 Firefox ≤68 -
-ms-user-select: none虽已废弃,但部分 Windows Mobile 或旧 WebView 仍依赖它 -
user-select: none一定放最后,避免被前缀规则意外覆盖
移动端 Safari 长按仍弹出菜单?补 -webkit-touch-callout
iOS Safari(尤其是 iOS 15–16)对 user-select: none 有额外绕过机制:只要元素绑了 ontouchstart,或父级设置了 cursor: pointer,长按就可能呼出“复制/翻译”浮层。
- 必须叠加
-webkit-touch-callout: none抑制长按菜单 - 若需彻底禁用,配合
ontouchstart="event.preventDefault()"(注意会阻断滚动) - 更稳妥做法:监听
selectstart事件并event.preventDefault()
input/textarea 里写 user-select: none 没用,这是设计使然
表单控件的文本选择行为由浏览器原生逻辑控制,CSS 的 user-select 层级低于其内部机制。哪怕父容器设了 user-select: none,<input> 里的文字照样双击可选、光标可定位。
- 无法用 CSS 禁止输入框内文本选择,这是规范行为,不是 bug
- 若真要干预,只能用 JS 拦截
selectstart或控制selectionStart/End - 注意
contenteditable="true"容器中user-select: none支持也不稳定,建议显式设为user-select: text再用 JS 控制
子元素继承问题:别让 span 暴露可选漏洞
user-select 不具有继承性,但子元素若未重置样式,可能保留默认 user-select: text,导致局部可选——尤其常见于图标文字混排场景。
- 避免在
user-select: none容器内嵌套未设样式的<span></span>、<em></em>等元素 - 统一重置子元素:
.unselectable * { user-select: none; }(注意兼容性,需补前缀) - IE10/11 中
-ms-user-select不支持all和contain,只认none、text、element
真正麻烦的不是写四行前缀,而是那些看似无关的触发条件:touchstart 监听器、cursor:pointer、contenteditable、甚至 flex 布局下子项未显式声明 -ms-user-select —— 它们都会让 user-select: none 在某个角落悄悄失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











