浏览器搜索高亮太普通,这招让它自动适配背景色,还能区分不同高亮?

2,757字
12–18 分钟
in

找东西的时候,浏览器那个黄不拉几的搜索高亮,是不是经常和页面背景糊在一起,根本看不清楚?更烦的是,有时候又是选中文本高亮,又是页面内搜索高亮,各种颜色搅成一团,根本分不清哪个是哪个。今天咱们就来盘一盘,怎么用CSS里新出的那个::search-text伪元素,再加上它的兄弟们,把页面上这些高亮效果拿捏得明明白白。

目录

啥是页面高亮伪元素

说白了,就是浏览器给页面上某些“被标记”的文字开的后门。平常按Ctrl+F搜出来的词,选中一段文字拖蓝的痕迹,甚至拼错的单词下面那条红线,都能用CSS单独控制它们的样式。

常用高亮伪元素

伪元素选择器作用对象默认样式
::search-textCtrl+F搜到的匹配词黄色背景
::target-text网址锚点跳转到的文字黄色背景
::selection鼠标拖蓝选中的文字蓝色背景
::spelling-error拼写错误的单词红色下划线
::grammar-error语法错误的单词绿色下划线

给搜索高亮换个皮肤

::search-text这哥们儿刚在Chrome 144里正式上岗,它的默认黄背景和橙色当前项(:current)经常在深色背景的页面上翻车。咱们直接上代码,教它怎么根据页面背景色,自己变出一个绝对不会瞎眼的高亮色。

动态反色方案

这个方案的思路很简单,就是把高亮的背景色,变成当前页面背景色的反色。这样不管背景是啥妖艳颜色,高亮都能稳稳地跳出来。

body {
  --bg-color: #38003c;
  background: var(--bg-color);
}

::search-text {
  /* 让高亮文字颜色和页面背景色一致 */
  color: var(--bg-color);
  /* 将背景色RGB通道值反向,得到反色背景 */
  background: rgb(from var(--bg-color) calc(255 - r) calc(255 - g) calc(255 - b));
}

/* 当前被激活的那个搜索项,给个更醒目的效果 */
::search-text:current {
  /* 保持反色逻辑,但可以加个透明度玩点花样 */
  background: rgb(from var(--bg-color) calc(255 - r) calc(255 - g) calc(255 - b) / 90%);
}

这里有个坑background-clip: text这类属性在高亮伪元素上是失效的,别想着用文字剪裁来整活。能折腾的主要就是colorbackground以及相关的透明度。

动手调整试试看

把上面这段代码贴到自己的样式表里,然后把--bg-color这个变量值换成自己页面的主背景色。打开浏览器,按一下Ctrl+F搜个词,是不是发现高亮色自动就变了个样?如果背景色是深紫色,那高亮就会变成浅黄绿色,跟背景色形成强烈反差。

解决多重重叠高亮互相打架

页面里经常会出现好几个高亮叠在一起的情况。比如先搜了个词(::search-text高亮),然后又把那段文字用鼠标拖蓝(::selection高亮),这时候两个颜色搅在一起,就看不清哪个是哪个了。得想办法给它们分分工。

为不同高亮定制专属皮肤

body {
  --bg-color: #38003c;
  background: var(--bg-color);
}

mark,
::selection,
::target-text,
::search-text {
  color: var(--bg-color);
}

mark {
  /* 全通道反色,适合普通标记 */
  background: rgb(from var(--bg-color) calc(255 - r) calc(255 - g) calc(255 - b) / 70%);
}

::selection {
  /* 保留红色通道不变,只反绿和蓝,让选中的文字偏红一些 */
  background: rgb(from var(--bg-color) r calc(255 - g) calc(255 - b) / 70%);
}

::target-text {
  /* 保留绿色通道,让它偏绿 */
  background: rgb(from var(--bg-color) calc(255 - r) g calc(255 - b) / 70%);
}

::search-text {
  /* 保留蓝色通道,让搜索结果偏蓝 */
  background: rgb(from var(--bg-color) calc(255 - r) calc(255 - g) b / 70%);
}

::search-text:current {
  /* 当前激活的搜索结果,保留蓝色通道且完全不透明,更醒目 */
  background: rgb(from var(--bg-color) calc(255 - r) calc(255 - g) b / 100%);
}

玩点小心机:给不同高亮留了不同通道的原色,这样它们叠在一起时,就能通过颜色差异看出谁是谁。比如搜索结果偏蓝,锚点跳转的文字偏绿,鼠标拖蓝的文字偏红,一眼就能分辨出来。

看效果

把代码更新后,再试试同一个词,先用Ctrl+F搜出来,再用鼠标去拖蓝那一段。现在应该能看到搜索高亮和选中高亮有了明显的颜色区别,就算重叠在一起,也能看出哪个是哪个。

思路二:不想用反色,想自己指定颜色

有些人可能觉得反色出来的颜色太“随机”,不够精致。那也行,手动指定颜色,但要确保在页面的各种背景上都看得清,特别是要考虑到深色模式。

:root {
  --highlight-search-bg: #ffcc00;
  --highlight-search-color: #1a1a1a;
  --highlight-selection-bg: #b3d9ff;
  --highlight-selection-color: #000000;
}

@media (prefers-color-scheme: dark) {
  :root {
    --highlight-search-bg: #ffaa33;
    --highlight-search-color: #111111;
    --highlight-selection-bg: #2a6f9c;
    --highlight-selection-color: #e0e0e0;
  }
}

::search-text {
  background-color: var(--highlight-search-bg);
  color: var(--highlight-search-color);
}

::selection {
  background-color: var(--highlight-selection-bg);
  color: var(--highlight-selection-color);
}

一点小提示:不管用哪种方案,高亮的文字颜色和背景色之间一定要去测一下对比度,特别是用反色方案时,遇到像#808080这种反色还是它自己的灰色,就翻车了。所以代码写完,记得用在线工具跑一遍颜色对比度检查。