HTML中无标签文本的CSS变色技巧

这篇文章发布于 2020年11月15日,星期日,18:11,归类于 CSS相关。 阅读 17830 次, 今日 4 次 2 条评论

 

文字彩色变色

一、考考你?

已知HTML如下:

<h4>原始标签效果</h4>
<ul>
    <li><input type="radio" name="item" checked>选项1</li> 
    <li><input type="radio" name="item">选项2</li> 
    <li><input type="radio" name="item">选项3</li> 
    <li><input type="radio" name="item">选项4</li> 
    <li><input type="radio" name="item">选项5</li> 
</ul>

请实现如下图所示的样式效果,纯CSS实现,包括点击的交互效果。

列表点击效果

对于这类点击交互效果,无论是单选还是多选,都可以使用:checked伪类技术实现,这个很多CSS开发人员都知道并熟练使用。

但是在本例中,UI效果实现的难点不在于选中行为本身,而是在HTML标签数量严重受限的情况下如果控制样式效果。

:checked伪类选择器是能控制后面包含HTML标签元素的样式效果,例如:

:checked + label { color: #009FF1; }

但是在本例中,Radio单选框元素后面是裸露的文字,也就是文字内容没有使用类似<label>的HTML标签包裹,选中时候的颜色又该如何控制呢?

二、混合模式改变无标签文本颜色

无标签文字颜色的控制,目前主要有两种方法:

  1. mix-blend-mode混合模式,系列文章参见这里
  2. backdrop-filter背景滤镜,相关介绍参见这里

无论哪种方法,都是通过图层定位到文字所在飞位置上方,然后应用CSS实现的。

其中,混合模式方法是性能较好,应用范围更广的一种方法。

因此,在本例中,就演示下如何使用CSS中的mix-blend-mode属性让没有标签的文字变色。

先看实际效果,您可以狠狠地点击这里:无标签文本CSS变色实现demo

兼容所有的现代浏览器,iOS和Android手机设备也均支持。

实现思路

在现代浏览器中,input单选框或者input复选框的样式是可以100%完全自定义的,并且和普通的HTML元素一样,支持::before, ::after伪元素,因此,本例效果实现的关键,就是:

  1. 干掉单选框默认样式;
    [type=radio] {
        -webkit-appearance: none;
        appearance: none;
        all: initial;
    }

    单选框UI和尺寸重置

  2. 伪元素创建选中的钩钩效果;
    [type=radio]:checked::before {
        content: '';
        position: absolute;
        top: 0; bottom: 0; right: 1rem;
        width: .6125rem; height: .325rem;
        margin: auto;
        border-left: 2px solid;
        border-bottom: 2px solid;
        transform: rotate(-45deg);
    }

    伪元素实现的选中效果

  3. 伪元素创建一个主色颜色覆盖层,然后设置混合模式为lighten;
    [type=radio]:checked::after {
        content: '';
        position: absolute;
        left: 0; top: 0; right: 0; bottom: 0;
        background-color: #009FF1;
        mix-blend-mode: lighten;
    }

其中,最后一句mix-blend-mode:lighten是实现的关键,lighten这种混合模式很好理解,就是各个混合图层进行对比,那个颜色浅就使用哪个颜色。

在本例中,如果不设置混合模式,则会是如下图所示的蓝色覆盖层效果:

蓝色背景色块效果

由于蓝色和黑色文字对比是蓝色浅,因此,原本黑色文字就会变成蓝色;而蓝色和白色背景对比,一定是白色浅,因此,原本白色的背景还是白色,最终的效果就是只有文字变成蓝色了,于是巧妙地实现了匿名文本元素的变色效果了。

上面这句话大家可以好好琢磨琢磨。

三、其他类似案例举例

在过去,纯前端实现是文字搜索高亮,一定是要给文字内容套一层标签的,这样才能改变匹配文字的颜色。

现在,有了混合模式,我们可以在不嵌套任何标签的情况下,让任意的文字颜色变色。

例如下面这个搜索高亮效果:

文字搜索高亮

就是通过获取匹配文字的位置,然后创建浮层,再应用叠加混合模式实现的,覆盖层的CSS代码如下所示:

ui-overlay {
    position: absolute;
    background: red;
    mix-blend-mode: overlay;
    z-index: 9;
}

眼见为实,您可以狠狠地点击这里:文字不嵌套实现搜索高亮效果demo

overlay叠加适合浅色文字的覆盖,如果是深色文字,则适合使用lighten这种混合模式。

然后,上面的demo页面仅仅是演示,实际上,最终的效果还是有bug的,就是如果搜索的文字内容正好在换行位置,则高亮的区域范围就有问题,这个问题也好解决,不过精力有限,就没有进一步深入。

四、旨在抛砖引玉

backdrop-filter也能改变底层文字的颜色,但是这个变色往往会影响其他元素的颜色。

也就是要么整体变色,要么只能适用于特定场景的变色。

例如亮度变化、色调变化。

例如,白底红色红色文字变成绿色文字,可以设置:

.overlay-color-change {
    backdrop-filter: hue-rotate(180deg);
}

因为白色色调变化依然是白色。

无论是混合模式还是背景滤镜改变文字颜色,都只适合颜色简单的视觉表现场景,如果是复杂图案这种,就无能为力了。

所以,大家需要根据实际情况判断该如何使用,该使用哪种混合模式,本文旨在抛砖引玉,给大家提供一种全新的不使用标签就能改变文字颜色(包括文字渐变或图案效果)的实现方式。

以上就是本文内容,感谢您的阅读,欢迎分享到你的朋友圈或者前端资讯群中!

(本篇完)

分享到:


发表评论(目前2 条评论)

  1. 闷闷不乐说道:

    在“文字不嵌套实现搜索高亮效果实例页面”这个demo中,有一个bug,如果把代码直接复制进jsbin或者codepen上,是无法看到效果的,需要将html和body的背景色置为一个浅色,比如白色等。至于为什么要置两次背景色,我还不知道。求指点。

  2. redbuck说道:

    有个小问题.
    页面尺寸变化,位置就不准确了,需要更新位置.

    不过有了新选项总是不错的.