加了 user-select: none 仍弹出“复制”菜单是因为 ios safari 需同时设置 -webkit-touch-callout: none 和多前缀 user-select 属性,且 input、textarea、contenteditable 等元素上该样式会被忽略。

为什么加了 user-select: none 还是弹出“复制”菜单
根本不是你写错了,而是 iOS Safari 的行为分两层:选中文本框(user-select 控制)和唤出气泡菜单(-webkit-touch-callout 控制)。只设 user-select: none,高亮可能压住,但长按后菜单照弹——这是 WebKit 渲染管线和系统策略共同决定的,CSS 无法单点突破。
-webkit-user-select: none 必须和哪些声明一起用
单独写任意一个前缀都不可靠。必须同时声明:
-
user-select: none(现代标准,Chrome/Firefox/Edge 基本认) -
-webkit-user-select: none(iOS Safari 和旧版 Android WebView 唯一认的) -
-moz-user-select: none(Firefox 移动端仍需) -
-ms-user-select: none(部分 Windows Mobile WebView 兼容)
漏掉 -webkit-,iOS 上基本等于没写;漏掉标准属性,新版 Chrome 可能回退到 auto。
哪些元素上加了也白加,反而坏事
user-select: none 在这些地方会被浏览器直接忽略,还可能破坏交互:
-
<input type="text">、<textarea></textarea>:焦点态下必然可选,强行加会干扰光标定位和输入法 -
[contenteditable="true"]:编辑能力优先级高于 CSS,禁用后富文本光标失灵 - 带
tabindex="0"或role="button"的容器:一旦获得焦点,Android Chrome 可能允许双击选中 -
<img>的alt文本:iOS 长按时仍可高亮,得设alt=""或改用背景图
真要控制输入区域,focus 时移除 class,blur 后恢复;或用 readonly + pointer-events: none 模拟只读态。
全局设 body { user-select: none } 的真实代价
看着省事,实际埋雷:
-
<pre class="brush:php;toolbar:false;"></pre>代码块无法复制,技术文档直接废掉 - 屏幕阅读器依赖文本可选性判断语义边界,WCAG 1.3.1 直接不达标
- React/Vue 中
v-html或dangerouslySetInnerHTML插入的内容,样式继承后无法通过 props 覆盖 - 漏掉任意一类重置(比如忘了
[contenteditable="true"] { user-select: text; }),用户点进编辑器就卡死
真正该防的是误触,不是文本本身——touch-action: manipulation 比盲目禁选更轻量、更安全。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











