::selection 要生效需同时写 ::-webkit-selection 和 ::selection 且样式完全一致,避开 user-select: none、作用域隔离、高权重选择器等干扰,并仅使用 color 与 background-color。

::selection 要真正起效,不是写对语法就行,而是得绕过浏览器一堆默认拦截和作用域陷阱。它大概率“不生效”,不是你漏了分号,而是被 user-select: none、<style scoped>、或 iOS 系统级菜单直接废掉了。
为什么写了 ::selection 却完全没反应
不是 CSS 写错了,是选中行为根本没触发:
-
user-select: none写在父容器(哪怕只是body)或自身上——文本压根不能被选,伪元素自然不运行 - 用 Vue 的
<style scoped>或 Shadow DOM 包裹——::selection不穿透作用域,样式被丢弃 - 页面里有更具体的选择器,比如
p::selection或.article::selection,权重高于全局::selection,把你写的规则覆盖了 - 用了 CSS-in-JS 库(如 styled-components)动态注入样式——前缀被删、作用域隔离、或规则没挂到
<head>,导致无效
排查方法:选中一段文字 → 打开 DevTools → 在 Styles 面板搜索 ::selection,看有没有匹配规则;再往上点 computed styles,检查 user-select 是否为 none。
::selection 和 ::-webkit-selection 必须同时写且内容一致
只写 ::selection 在 Chrome、Edge(Chromium)、新版 Safari 里大概率失效。WebKit/Blink 内核浏览器强制要求显式声明 ::-webkit-selection,且两个规则的声明必须完全相同:
- 属性名、值写法(比如都用
#3b82f6,别一个用rgb()一个用hex)必须一致 -
::-moz-selection已废弃,Firefox 100+ 只认::selection,不用加 -
::-webkit-selection建议放在前面,::selection放最后作标准兜底 - PostCSS autoprefixer 默认不处理这两个伪元素,如果用了构建工具,得确认它没把
::-webkit-selection给删掉
正确写法示例:
立即学习“前端免费学习笔记(深入)”;
::-webkit-selection { color: white; background-color: #3b82f6; }
::selection { color: white; background-color: #3b82f6; }
::selection 只认 color 和 background-color,其他全被静默忽略
它不是普通选择器,规范只允许修改极少数属性:
- ✅ 必须同时设置的两个:
color(文字色)、background-color(背景色)——缺一不可。只设background-color时,文字可能继承默认黑色,在深色背景上直接“消失” - ⚠️ 有条件支持:
text-shadow(Firefox 和 Chrome 支持;Safari 15.4+ 才开始认),cursor(仅悬停时生效,极少用) - ❌ 完全无效:
font-size、border、padding、background-image、transform、opacity、calc()计算值、CSS 变量混合(如color-mix()) - 别用
rgba()或hsl()带 alpha 的颜色值——Safari 渲染不稳定,深色背景上可能发灰或透明,优先用十六进制不透明值,比如#3b82f6 -
background简写有时会失效,必须用全称background-color
input 和 textarea 里改不了选中色
这不是你 CSS 写错了,是浏览器有意限制:
- 原生表单控件对
::selection的支持极不稳定。Chrome 下input[type="text"]基本不响应,textarea则部分生效但行为不一致 - 某些旧版 Safari 甚至把
textarea里::selection的color当背景色渲染 - 想统一控制,只能用
contenteditable="true"替代input(需自行处理值同步、焦点、a11y) - 真正难处理的是当用户长按唤起系统级选择菜单时,iOS 会强制使用浅灰背景,此时
::selection完全不生效——这是系统行为,CSS 无权干预
复杂点在于:它既不是纯样式问题,也不是兼容性补丁能一劳永逸的事。关键动作就三步:写对两个伪元素、显式声明两个颜色、避开那些“看起来能用但其实废”的属性。剩下全是环境干扰,得一个个排除。


















