CSS Custom Highlight API:实现文字彩虹色效果

190 阅读3分钟

作为一名前端开发者,曾经为文本高亮效果感到为难!!传统的 ::selection 伪元素只能实现简单的背景色和文字颜色调整,想要更个性化的高亮效果,似乎总是束手无策。

但现在,一切都不同了!

CSS Custom Highlight API 的出现🎉,为文字效果打开了一扇新的大门,一个浏览器原生支持的 CSS 文本高亮功能。它允许我们通过 JavaScript 动态创建高亮范围,可以在不改变 dom 结构的情况下自定义任意文本的样式,真正实现“高亮自由”!

什么是 Custom Highlight API?

简单来说,它是一个全新的 CSS 特性,让我们可以:

  1. 通过 JavaScript 选择任意文本范围。
  2. 用 CSS 为这些范围定义独特的高亮样式。
  3. 实现更灵活、更个性化的高亮效果,比如彩虹色文本、搜索高亮、代码高亮编辑器,甚至动画!

要定义高亮文本颜色需要css和js才能实现。

一、css伪元素,::highlight()

::highlight(自定义name){
    color:#8B00FF;
}

注意:这里的自定义name由js定义得来。

::highlight()支持下面几种样式设置:

  • color
  • background-color
  • text-decoration
  • text-shadow
  • -webkit-text-stroke
  • -webkit-text-fill-color

二、js部分

1.创建 Highlight 对象

使用 Highlight 构造函数创建一个高亮对象。

const highlight = new Highlight();

2.选择文本范围

使用 Range 对象选择要高亮的文本。

 <div class="box" id="ex1">抓去种芹菜</div>
const textNode = document.getElementById( 'ex1' ).firstChild;
const range = new Range();
range.setStart(textNode, 1);//startOffset,文本开始位置
range.setEnd(textNode, 4);//endOffset,文本结束位置

3.将文本范围添加到高亮对象

将 Range 对象添加到 Highlight 对象中。

highlight.add(range);

4.注册高亮对象

使用 CSS.highlights.set() 方法注册高亮对象,并为其命名。

CSS.highlights.set('highlight1', highlight);

5.使用 CSS 定义高亮样式

通过 CSS 定义高亮样式,使用 ::highlight() 伪元素选择器。

::highlight(highlight1) {
  background-color: yellow;
  color: black;
}

效果图如下:

微信截图_20250208140005.png

也可以给文字加上波浪线。

::highlight(highlight1) {
  background-color: yellow;
  color: black;
  text-decoration:underline wavy red;
}

效果图如下:

微信截图_20250208140329.png

Highlight的优点有以下几点:

  • 更自由的控制:不再局限于浏览器的默认高亮行为,你可以为任何文本赋予独特的视觉效果。
  • 更丰富的交互:结合 JavaScript,可以实现动态高亮,比如根据用户输入实时标记关键词。
  • 更优雅的代码:告别繁琐的 DOM 操作,用更简洁的方式实现复杂的效果。

注意:在以上代码实际实践的过程中,刚开始一直没有出现效果,反复检查了好久,才发现是换行的问题,实际dom节点里有很多空格,导致选择文本范围时选中了空格,所以没有出现效果,我的解决办法是: 1.文字不换行; 2.修改文本选择范围的值。希望可以有更好的解决办法。

三、彩虹色文字效果

微信截图_20250208141209.png

实现代码:

//html,js
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>彩虹色文字效果</title>
  <link rel="stylesheet" href="./css/highlight.css">
</head>

<body>
  <div class="wrap">
    <div class="box" id="ex1">
      少年没有偏旁,自己便是华章。
    </div>
  </div>
  <script>
    const textNode = document.getElementById( 'ex1' ).firstChild;
    if(CSS.highlights){
      const highlights =[];
      for(let i=0;i<7;i++){
        //给彩虹色的每个颜色实例化一个highlight对象
        const colorHighlight = new Highlight();
        highlights.push(colorHighlight);
        //注册高亮对象
        CSS.highlights.set(`rainbow-${i+1}`,colorHighlight);
      }
      // 选择文本范围
      for(let i=0;i<textNode.length;i++){
        // 选择文本范围
        const range = new Range();
        range.setStart(textNode,i);
        range.setEnd(textNode,i+1);
        // 将范围添加到高亮对象
        highlights[i%7].add(range);
      }
    }
  </script>
</body>
::highlight(rainbow-1){
  color: #ff0000;
}
::highlight(rainbow-2){
    color:#FFA500;
}
::highlight(rainbow-3){
    color:#ffff00;
}
::highlight(rainbow-4){
    color:#00ff00;
}
::highlight(rainbow-5){
    color:#00ffff;
}
::highlight(rainbow-6){
    color:#0000ff;
}
::highlight(rainbow-7){
    color:#8B00FF;
}

在实际代码编写中,需要判断一下浏览器对Highlight的兼容性。此外,如果文字里面有换行等字符,取文本时不会被全部选择,需按照实际需求修改。


💻工作是一场永不止息的探索!✨