一种更好的文字隐藏的方法-::first-line伪元素

这篇文章发布于 2025年03月17日,星期一,01:04,归类于 CSS相关。 阅读 160 次, 今日 157 次 没有评论

 

first-line封面占位图

一、前言

去年年中开始开启了《CSS世界》三部曲精讲视频系列,然后前段时间正好讲到::first-line伪元素,突然意识到,很长一段时间内,我居然把这个东西给忘记了。

::first-line伪元素本身的作用是个鸡肋,就是控制第一行文字的样式。

但是其衍生的作用倒是有个妙用,那就是隐藏按钮或者图标内的文字的同时不改变color属性的上下文。

例如,LuLu UI中的按钮控件,其按钮的loading效果是隐藏文字,显示旋转图标🌼,按钮尺寸不变,如下GIF动图所示。

loading效果截图示意

其中有个要求,那就是loading旋转图标的颜色要和文字保持一致,我们很自然会想到currentColor关键字,或者颜色不指定,直接继承。

这就会产生一个矛盾的点,那就是如果我们使用类似下面的语句隐藏文字:

button {
  color: transparent;
}

那么图标的颜色也会变成transparent,因为图标颜色和文字颜色是一致的。

那么有没有什么办法可以让文字隐藏,又不影响color属性的上下文呢?

二、一直使用的是-webkit-text-fill-color

我这些年一直使用的是-webkit-text-fill-color属性来设置文字隐藏的,此属性虽然是-webkit-私有前缀,但是Firefox浏览器也是支持的,加上现在IE浏览器已经名存实亡,因此,还用得不错。

text-fill兼容性

相关代码如下所示,只展示关键部分:

button {
    /* 略... */
}
button.loading::before {
    content: '';
    width: 20px; height: 20px;
    box-sizing: border-box;
    border: 2px solid;
    border-top-color: transparent;
    border-radius: 50%;
    position: absolute;
    inset: 0;
    margin: auto;
    animation: spin 1s linear infinite;
}
button.loading {
    -webkit-text-fill-color: transparent;
}

此时,给按钮元素增加类名loading,文字就会隐藏,但是又不会影响loading图形的颜色。

三、::first-line似乎更合适

实际上,这里可以还可以使用::first-line伪元素,兼容性更好,记忆成本也更低。

相关代码实现示意:

button {
    /* 略... */
}
button.loading::before {
    /* 同上... */
}
button.loading::first-line {
    color: transparent;
}

非常巧妙的一种实现。

下图所示的就是上面两种方法实现的效果GIF示意图:

点击我loading效果示意

完整代码

实际演示效果和完整代码,您可以狠狠地点击:

不影响color上下文按钮文字透明demo

☝️🖕☝️🖕

三、铁树开花,思路延伸

除了保留color上下文,::first-line伪元素,包括上面提到的-webkit-text-fill-color属性还有一个有用的特性,就是有更高的文字颜色重置优先级。

我举个例子,大家就知道什么意思了,比方说有这样一段HTML代码:

<button id="button" class="button">按钮</button>

然后按钮以很高的选择器优先级设置了一个颜色,例如:

#button {
   color: blue !important;
}

然而,按钮禁用的时候,文字颜色要是灰色,得,优先级如此高,怎么重置?再使用一个!important吗?

无需!

下面两段CSS都可以重置上面的蓝色设置:

button:disabled {
  -webkit-text-fill-color: gray;
}
button:disabled::first-line {
  color: gray;
}

如果两者同时使用,根据我的测试,text-fill-color属性要更生猛一些,会覆盖::first-line的颜色设置。

好,本文就这么多内容。

哎呀,好久没写东西写到快1点,就不唠嗑了,直接结尾。

我们下篇文章再见!

👋👋👋👋

(本篇完)

分享到:


发表评论(目前没有评论)