先记住这个答案
::selection 伪元素让你自定义用户选中文字时的高亮样式。默认情况下浏览器用蓝色背景加白色文字来显示选区。用 ::selection 可以换成品牌色或其他风格。但能用的 CSS 属性非常有限,规范只允许 color、background-color、text-shadow、text-decoration 这几个,盒模型和字体相关的属性都不行。
::selection只作用于选中的文字background-image不能用- 可以针对特定元素单独设置
- 注意对比度的可访问性
基本写法和属性限制
全局设置选中样式很简单,只需要一个选择器。也可以针对特定元素单独设置,比如代码块用不同的选中颜色。
/* 全局:选中文字时用品牌色 */
::selection {
background-color: #1a73e8;
color: #fff;
}
/* 代码块:选中时用暗色背景 */
pre::selection,
code::selection {
background-color: #263238;
color: #80cbc4;
}写 ::selection 时不用写 content 属性(和 ::before 不同),因为它不是生成新内容,而是给已有内容的选中状态加样式。
能用的属性完整列表:color、background-color、text-shadow、text-decoration、-webkit-text-stroke-color、-webkit-text-fill-color、stroke-color、fill-color。除此之外的属性写了也没效果,浏览器会忽略。background-image(包括渐变)不被支持,想用渐变背景做选中效果是做不到的。
可访问性:对比度和可读性
改 ::selection 样式时最容易犯的错是只改背景不改文字颜色。比如把背景改成浅黄色,但文字还是默认的白色,选中后根本看不清。
正确的做法是 background-color 和 color 一起改,保证对比度足够。WCAG 建议文字和背景的对比度至少达到 4.5:1。
/* 错误:浅背景 + 浅文字,看不清 */
::selection {
background-color: #fff3cd;
/* 没写 color,默认白色文字看不清 */
}
/* 正确:浅背景 + 深文字 */
::selection {
background-color: #fff3cd;
color: #333;
}有些设计会把 ::selection 的背景设成透明或非常浅的颜色。这在深色模式下尤其危险——深色背景上选中文字如果高亮太浅,用户可能完全看不出选中了什么。
不继承和不冒泡
::selection 有一个反直觉的行为:它不从父元素继承。如果在 body::selection 上设置了颜色,body 里面的 <p> 不会自动继承这个选中样式。要让所有元素生效,要么用 ::selection(不带元素选择器,匹配所有),要么给每个需要的元素单独写。
这也是为什么推荐在全局用不带前缀的 ::selection {} 而不是 body::selection {}。前者对所有元素生效,后者只对 <body> 的直接文本节点生效。
容易答错的地方
- 以为可以用 background-image 或渐变
background-image、linear-gradient这些在::selection里写了也没效果。以前某些浏览器短暂支持过渐变背景,但后来被移除了。只能用纯色background-color。- 以为修改了全局 selection 就不用管子元素
- 如果页面某个元素自己有
::selection样式,它会完全覆盖全局设置,不存在「合并」。比如全局设了蓝色背景,某个<div>只设了::selection { color: red; },那个<div>里选中文字的背景会变回浏览器默认值(蓝色),不会沿用全局的蓝色。
面试官还会怎么问?
怎么禁止用户选中文字?
用 user-select: none。这是一个独立的 CSS 属性,和 ::selection 无关。user-select: none 让元素的文字完全不可选,::selection 是改变选中后的样式。两者解决的问题不同。
selection 能用在图片上吗?
<img> 元素本身的文字不可选(因为它是置换元素),所以 img::selection 没有意义。但图片的 alt 文字在某些情况下可选(比如图片加载失败时),这时 ::selection 理论上可以生效。
暗色模式下 selection 样式要单独处理吗?
是的。用 @media (prefers-color-scheme: dark) 包裹一套暗色模式的 ::selection 样式。深色背景下默认的蓝色选中背景对比度可能不够,需要换一个更亮的颜色。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。