文本动效Background-clip和文本高亮highlight

330 阅读4分钟

大家曾经可能在各种网站上看到各种镂空,渐变等炫酷的文字效果。但是实际开发中可能接触的很少,下面为大家揭秘一下这是如何实现的。

背景裁剪Background-clip

这个属性字面上其实是背景裁剪的意思,那么又是如何实现文字的渐变呢?我们来看下面这个例子

 <div class="testText">测试文本</div>


.testText {
    width: fit-content;
    font-size: 50px;
    font-weight: bold;
    color: transparent;
    background: linear-gradient(45deg, #ffeb3b, #009688, yellowgreen, pink, #03a9f4, #9c27b0, #8bc34a);
    -webkit-background-clip: text;
  }

image.png

实际上渐变的效果是借助background的渐变属性linear-gradient实现的,background-clip起到的作用是根据文字来裁切背景,再把文字颜色设为透明,即可实现渐变文字的效果。

既然是裁切背景得到的文字效果,那背景当然可以是图片,甚至是动图,代码如下

<div class="testText2">
    测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本
    测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本
    测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本
    测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本
    测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本
    测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本
    测试文本测试文本测试文本测试文本测试文本测试文本测试文本
</div>

.testText2 {
    width: 50%;
    font-size: 50px;
    font-weight: bold;
    color: transparent;
    background: url(https://media.giphy.com/media/Ju7l5y9osyymQ/giphy.gif) center/cover;
    -webkit-background-clip: text;
  }

我们把之前的渐变色直接替换成动图,整段文字就可以循环播放炫酷的动图的内容。

在此基础上,我们还可以更进一步,直接让文字勾勒出人物形状

.testText3 {
    width: 50%;
    font-size: 50px;
    color: transparent;
    background: url('https://media.giphy.com/media/Ju7l5y9osyymQ/giphy.gif') center/cover;
    -webkit-background-clip: text;
    filter: grayscale(1) invert(1);
    mix-blend-mode: hard-light;
  }

image.png

这里用到了一个新属性filter,这也是一个非常强大的属性,我们这里用到它的两个功能,首先是grayscale(1)将彩色变成黑白,再用了invert(1)反转输入图像的色值,就得到了这种及其夸张的特效。

浏览器兼容性

image.png

文本高亮highlight

之前遇到的很多高亮都是通过截取文本然后在其中插入特定的span标签来实现底色的区分,实现起来比较复杂。

下面介绍一种原生高亮方法::highlight

<div id="test">自定义高亮测试</div>

<script>
const parentNode = document.getElementById("test").firstChild;
 const range1 = new Range();
  range1.setStart(parentNode, 1);
  range1.setEnd(parentNode, 2);

  const highlight1 = new Highlight(range1);
  CSS.highlights.set("highlight1", highlight1);
</script>

<style>
 ::highlight(highlight1) {
    background-color: red;
    color: white;
  }
</style>

 这样看上去就十分简单的实现了一个文本高亮效果。首先准备一个需要高亮的节点,在js中获取这个节点。然后声明一个高亮开始和结束的范围,接着在new 一个 highlight1传入范围range1。最后用CSS.highlights.set设置这个文本高亮。在css中定义一个与之对应的::highlight,设置需要高亮的字体颜色和背景色,这样我们就实现了一个简单的文本高亮效果。

在实际的业务场景中,可能是给一组高亮的数据,然后前端对应渲染高亮的文本,案例如下

<div id="test">自定义高亮测试</div>

<script>

const parentNode = document.getElementById("test").firstChild;
const actualHighlight = [
    { id: 4, start: 1, end: 2 },
    { id: 5, start: 3, end: 5 },
  ]

  const rangeList = []

  for (const item of actualHighlight) {
    const range = new Range();
    range.setStart(parentNode, item.start);
    range.setEnd(parentNode, item.end);
    rangeList.push(range)
  }
  const highlight = new Highlight(...rangeList);
  CSS.highlights.set(`test`, highlight);
</script>

<style>
 ::highlight(test) {
    background-color: pink;
    color: white;
  }
</style>

如此我们就实现了实际业务需求的高亮效果,比传统的插入span节点的方法简便了许多。

::highlight的优势

由上述案例可以看到::highlight最直观的优势就是避免了繁重的dom操作,极大的简化了写法。既然去除了dom操作者一环,那就省去了创建,移除dom等等性能开销很大的操作,所以性能也得到了极大的提升!

::highlight的局限性

虽然这种方式实现的文本高亮非常简单,且性能好,但是由于高亮没有实际对应的dom节点,所以有些高亮悬浮展示信息的效果没法实现!

所以在实际使用中面对复杂或者定制的高亮逻辑还有一点局限性 。

浏览器兼容性

image.png