是不是每次在网页上用Ctrl+F查找关键词,看着那一大片默认的黄色高亮,总觉得跟整个页面的设计格格不入?特别是深色背景的网站,那种亮黄色简直晃眼。现在Chrome 144版本悄悄上线了一个叫::search-text的新玩意儿,专门用来给浏览器自带的搜索匹配结果换衣服,配合其他几个早就存在的高亮伪类,终于能让页面里那些“不速之客”跟整体风格和谐相处了。
搜索高亮伪类家族
主力干将::search-text
::search-text这个伪元素是专门用来对付Ctrl+F查找出来的匹配文本。默认情况下,当前选中的那个匹配结果会用橙色打底,其他匹配项则是黄色。通过这个选择器,能轻松把这两种颜色都换成想要的任何样式。比如给所有匹配项换上淡蓝色背景,当前激活的用深蓝色。
容易混淆的::target-text
::target-text针对的是URL片段高亮,也就是网址后面带着#:~:text=这种参数时自动跳转并高亮的那段文字。搜索引擎给搜索结果页跳转时经常用这招,所以这俩伪类常常被搞混。区别在于触发方式完全不同:一个是手动按快捷键搜出来的,一个是点链接自动定位过去的。
其他高亮成员
| 伪类 | 选择对象 | 使用场景 |
|---|---|---|
| ::selection | 鼠标框选文本 | 用户拖拽选中的内容 |
| ::highlight() | JS自定义高亮 | 配合Custom Highlight API |
| ::spelling-error | 拼写错误 | 主要针对可编辑区域 |
| ::grammar-error | 语法错误 | 主要针对可编辑区域 |
还有个<mark>标签,是HTML层面的高亮元素,虽然不算伪类,但视觉效果上经常跟这些家伙混在一起。
动手搞定高亮样式适配
准备一个测试页面
先搭个基础架子,确保所有高亮元素都能被样式影响到。这里用一个深色背景作为例子,看看怎么让搜索高亮既醒目又不违和。
<body style="background: #38003c; color: white; padding: 20px;">
<p>这段文字里有需要搜索的关键词,比如“示例”和“代码”。按下Ctrl+F搜一下试试,默认的高亮是黄色的。</p>
<p>第二个段落也放一个“示例”,看看多个匹配项怎么显示。</p>
</body>应用基础样式
直接给这几个高亮家伙统一设置样式。这里用了一个取巧的办法:把高亮的文字颜色设成跟背景色一样,背景色则取背景色的反色。这样不管页面背景怎么变,高亮都能自动反色,保证看得清。
body {
--bg-color: #38003c;
background: var(--bg-color);
}
mark,
::selection,
::target-text,
::search-text {
color: var(--bg-color);
background: rgb(from var(--bg-color) calc(255 - r) calc(255 - g) calc(255 - b));
}如果浏览器不支持这个相对颜色语法,可以用预先算好的颜色值代替。但用相对颜色语法的好处是,只要改了--bg-color变量,所有高亮颜色都会跟着变,不用手动调。
区分不同高亮类型
把每种高亮做成不同颜色,这样要是页面同时出现多个高亮区域(比如用鼠标框选了一段文字,这段文字里又包含搜索匹配项),能一眼看出谁是谁。这里玩了个小花招:每种高亮只反转部分颜色通道,再带上透明度,重叠的地方就能看出层次。
mark {
/* 全通道反转,加70%透明度 */
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%);
&:current {
/* 当前匹配项去掉透明度,更加醒目 */
background: rgb(from var(--bg-color) calc(255 - r) calc(255 - g) b / 100%);
}
}用透明度叠加的好处是,当::selection和::search-text重叠时,两种半透明颜色混在一起会产生第三种颜色,边界清晰可见。::search-text:current用100%不透明,确保正在定位的那一项最突出。
特殊成员单独处理
::spelling-error和::grammar-error这俩家伙在可编辑区域(比如<textarea>或contenteditable元素)里,浏览器已经给了一套默认的红色波浪线(拼写错误)和绿色波浪线(语法错误)。强制改掉这些波浪线可能会让用户困惑,毕竟大家已经习惯了这套视觉语言。所以一般不动它们,除非有特殊需求,比如跟整体品牌色保持一致。
<textarea rows="4" style="background: #1e1e2f; color: white;">
这段文字里故意写个错误拼写 "helllo",看看浏览器怎么显示。
</textarea>浏览器会自动给可疑单词标红波浪线,不需要额外写样式干预。
完整解决方案代码
把上面的片段拼起来,就是一个能自动适应背景色的高亮方案。改--bg-color变量的值,所有高亮颜色都会跟着变,省去了挨个调色的麻烦。透明度的设置让不同高亮重叠时依然能分辨清楚,当前搜索项用100%不透明确保一眼定位。
:root {
--bg-color: #38003c;
}
body {
background: var(--bg-color);
color: white;
padding: 20px;
}
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%);
}如果背景色是#808080这种纯灰色,反色计算会得到#808080,文字就跟背景糊在一起了。遇到这种情况,可以手动给特殊背景写个备用样式,或者直接用对比度更高的颜色。实际项目里可以先用工具跑一下对比度检查,确保万无一失。
