likes
comments
collection
share

😎 纯 CSS 文字特效

作者站长头像
站长
· 阅读数 88

前言

封面中那样的文字特效是不是有点赛博朋克的感觉呢?这样的特效是如何用纯CSS实现的呢?本篇文章会带你探讨一下,也欢迎读者们评论指点

思考实现

从特效的效果来看,能够发现它有一个来回滚动的光标,并且光标的左侧是有赛博朋克风格的灯光特效,而右侧则是普通的文字,那么我们就要往光标的这个方向去靠,想办法通过一个属性控制光标的移动,这样就能在动画关键帧中通过控制这个属性来完成光标移动了

可以通过伪元素的方式去实现这个功能,我们可以用一个和文本内容一样的伪元素,将文本内容颜色设置成灰色,而伪元素的文本颜色则设置成特效颜色

通过伪元素的width属性去控制伪元素的宽度,这样当宽度不断变化时,就能够实现光标移动的效果了

但是有一个问题,由于我们的限制是纯CSS,所以我们不能通过js去设置伪元素的内容,那这该怎么办呢?可以使用attr()这一 CSS 表达式

CSS 表达式 -- attr()

MDN中对该表达式的介绍如下:

CSS 表达式 attr() 用来获取选择到的元素的某一 HTML 属性值,并用于其样式。它也可以用于伪元素,属性值采用伪元素所依附的元素。

这样一来我们可以通过在文本元素上添加一个data-text-effect-content这样的自定义数据属性,其值和文本元素的文本内容一样,这样就能通过attr(data-text-effect-content)设置伪元素的content值了

代码实现

用户角度使用文字特效

有了以上的思路,我们可以开始尝试写代码了,首先我的设计是,用户在使用的时候只需要添加text-effect这个类名,并且指定data-text-effect-content自定义数据属性的值就可以让这个文字特效生效

所以在用户的角度来看,用起来就像这样:

<h1 class="text-effect" data-text-effect-content="Hello Juejin!☺">Hello Juejin!☺</h1>

通过伪元素宽度控制特效移动

然后我们就专心实现.text-effect相关样式即可,由于要使用伪元素,所以需要先将文本元素的position设置为relative

.text-effect {
  /* 特效颜色 */
  --effect-color: #2e84d8;
  /* 无特效时的普通文本颜色 */
  --normal-color: #2a323d;
  position: relative;
  color: var(--normal-color);
}

这里为了语义化,使用了css变量

然后我们再去编写伪元素的样式代码,正如前面所说,我们先来使用attr()设置伪元素的content

.text-effect::before {
  content: attr(data-text-effect-content);
  position: absolute;
  color: var(--effect-color);
}

现在的效果如下:

😎 纯 CSS 文字特效

目前伪元素是完全覆盖掉文本元素的,我们通过修改width来改变其宽度

.text-effect::before {
  content: attr(data-text-effect-content);
  position: absolute;
  color: var(--effect-color);
+ width: 66px;
}

现在效果如下:

😎 纯 CSS 文字特效

文字长度超出了伪元素的宽度,导致发生了折行,我们可以通过white-space: nowrap来取消折行显示,但是这样的话文本又会显示在一行,然后导致覆盖了文本元素,所以我们还需要用overflow: hidden将超出伪元素宽度的那部分文本给隐藏掉

.text-effect::before {
  content: attr(data-text-effect-content);
  position: absolute;
  color: var(--effect-color);
  width: 66px;
+ white-space: nowrap;
+ overflow: hidden;
}

😎 纯 CSS 文字特效

那接下来就简单了,我们定义一个简单的动画关键帧,去修改伪元素的宽度即可

@keyframes text-effect {
  0%,100% {
    width: 0;
  }

  50% {
    width: 100%;
  }
}

记得给伪元素应用上这个动画

.text-effect::before {
  content: attr(data-text-effect-content);
  position: absolute;
  color: var(--effect-color);
  width: 66px;
  white-space: nowrap;
  overflow: hidden;
+ animation: text-effect 4s linear infinite;
}

😎 纯 CSS 文字特效

果然这个方案是可行的,但是这里有个问题,Juejinjin中的j没有被特效覆盖到,这可咋办?我们把伪元素的高度设置高一些就好啦!(简单粗暴)

.text-effect::before {
  content: attr(data-text-effect-content);
  position: absolute;
  color: var(--effect-color);
  width: 0;
+ height: 120%;
  white-space: nowrap;
  overflow: hidden;
  animation: text-effect 4s linear infinite;
}

😎 纯 CSS 文字特效

右侧光标

光标的话我们直接通过一个border-right就可以搞定

.text-effect::before {
  content: attr(data-text-effect-content);
  position: absolute;
  color: var(--effect-color);
  width: 0;
  height: 120%;
  white-space: nowrap;
  overflow: hidden;
  animation: text-effect 4s linear infinite;
+ border-right: 1rem solid var(--effect-color);
}

😎 纯 CSS 文字特效

赛博朋克灯光特效

最后我们要加上这个特效的灵魂 -- 赛博朋克灯光特效,这个要如何实现呢?

可以使用filter属性的drop-shadow,MDN 中关于该属性的介绍如下:

😎 纯 CSS 文字特效

通过它我们就可以实现阴影的效果,这里我们主要通过叠加第三个参数blur-radius,实现赛博朋克的那种雾化灯光的模糊特效

.text-effect::before {
  content: attr(data-text-effect-content);
  position: absolute;
  color: var(--effect-color);
  width: 0;
  height: 120%;
  white-space: nowrap;
  overflow: hidden;
  animation: text-effect 4s linear infinite;
  border-right: 1rem solid var(--effect-color);
+ filter: drop-shadow(0 0 30px var(--effect-color))
+ drop-shadow(0 0 60px var(--effect-color));
}

最终效果如下:

😎 纯 CSS 文字特效

至此,我们就通过纯CSS的方式实现了一个酷炫的文字特效啦!

转载自:https://juejin.cn/post/7152523727517941790
评论
请登录