user-select: none 并非万能,需配合前缀、规避表单元素、处理iOS长按及pointer-events等干扰因素才能生效。
user-select: none 是最直接的方案,但单独写这一条几乎必然失效——它不继承、对 <input> 和 <textarea> 完全无效,iOS 长按仍弹系统菜单,旧版浏览器还缺前缀。
常见失效原因不是语法错,而是语义和作用域理解偏差:
.card { user-select: none; },子元素如 <span> 或图标字体仍默认可选,除非显式再设一遍user-select 影响 <input>、<textarea>、<select> —— 这不是 bug,是设计如此!important、contenteditable="true" 属性、或父级 pointer-events: none 都会让 user-select 失效仅写 user-select: none 在 Safari 15.4 之前、部分 Android WebView、Edge 12–18 中会彻底失效。最小安全写法必须包含前缀:
.no-select {-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;}
注意:-o-user-select 和 -khtml-user-select 已无必要;-ms-user-select 对 Edge 12–18 用户仍有实际意义,别省。
绝对不要用 * { user-select: none; } 全局重置——它会让所有 <button>、<input>、<select> 失去焦点能力,用户点不了按钮、输不了字。
user-select 在它们身上从一开始就不该用。可行路径只有一条:
readonly 属性:这是最轻量、最可靠的方式,既阻止编辑,也自然失去文本选择焦点background: #f5f5f5; cursor: default;,让用户感知“不可操作”user-select 对它无解,现代浏览器没有标准 API 能只禁选不允编辑pointer-events: none:它会同时禁掉聚焦、光标定位、键盘输入,体验比“可选”还差Safari on iOS 对 user-select: none 响应有延迟,长按大概率唤出“复制/查找/翻译”菜单。必须额外加:
.no-select {-webkit-touch-callout: none;/* 其他 user-select 规则保持不变 */}
这条只对 iOS WebKit 生效,不影响其他平台。没有它,禁选在移动端基本形同虚设。
真正难的不是写几行 CSS,而是判断哪些元素该禁、哪些该放行、哪些根本禁不了——比如一个带搜索框的卡片区域,你得把禁选范围精确控制在描述文字上,而不是整个卡片容器。