「原生练手」纯CSS打造酷炫霓虹灯loading bar特效

2,122 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

本篇文章我们要来实现一个酷炫的霓虹灯特效的加载条loading bar的特效,如下图所示:

loading bar.gif

可以看到,这个loading bar的周围有霓虹灯一样的朦胧美感,而且底部还有一个倒影,这是怎么做到的呢?

相关知识点

首先要介绍一下这个demo要用到的知识点:

  • linear-gradient实现颜色渐变,颜色渐变的方向默认是从上往下的,当linear-gradient函数的第一个参数传入一个正角度的时候,渐变轴会逆时针旋转相应角度,由于我们的loading bar是从左往右运动的,所以渐变方向也应当设置成90deg
  • filter: blur()实现霓虹灯特效,使用::before渲染渐变色背景,再用一个相同的::after套上filter: blur()就可以实现霓虹灯特效了
  • -webkit-box-reflect实现底部倒影的效果,但是这个样式有兼容性问题,mdn上并不推荐使用,可以选择用element()函数替代,感兴趣的可以自行了解,这里我只是为了方便就使用这个样式了哈哈
  • @keyframes定义并使用流动动画

HTML

页面结构很简单,就一个div即可

<div class="loading-bar"></div>

CSS

.loading-bar

首先根据上面的分析,我们先来实现一下渐变色,由于要用::before伪元素绝对定位到.loading-bar中作为背景,所以首先要给.loading-bar设置成position: relative

.loading-bar {
  position: relative;
  width: 500px;
  height: 30px;
  background-color: white;
  border-radius: 12px;
}

使用伪元素实现渐变色背景和霓虹灯特效

然后添加两个伪元素::before::after,它们的样式是一模一样的,只是让::after多了一个filter: blur(10px)实现霓虹灯的一个特效

.loading-bar::before {
  content: "";
  position: absolute;
  inset: 0;
  /* 默认角度是从上到下,90deg 逆时针旋转后变成从左到右渐变 */
  background: linear-gradient(
    90deg,
    var(--gradient-color-1),
    var(--gradient-color-2),
    var(--gradient-color-3),
    var(--gradient-color-4),
    var(--gradient-color-1),
    var(--gradient-color-2),
    var(--gradient-color-3),
    var(--gradient-color-4),
    var(--gradient-color-1)
  );
  background-size: 200%;
  border-radius: 12px;
}
/* 使用一个和 ::before 相同的 作为霓虹灯特效 */
.loading-bar::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    var(--gradient-color-1),
    var(--gradient-color-2),
    var(--gradient-color-3),
    var(--gradient-color-4),
    var(--gradient-color-1),
    var(--gradient-color-2),
    var(--gradient-color-3),
    var(--gradient-color-4),
    var(--gradient-color-1)
  );
  background-size: 200%;
  filter: blur(10px);
  border-radius: 12px;
}

这里渐变色使用css变量的方式定义后使用,不然直接把颜色的十六进制写进去可读性太低了

:root {
  --gradient-color-1: #b983ff;
  --gradient-color-2: #94b3fd;
  --gradient-color-3: #94daff;
  --gradient-color-4: #99feff;
}

这时候的效果如下:

image.png

怎么样,是不是已经有霓虹灯内味儿了?

添加倒影

只需要给.loading-bar添加上-webkit-box-reflect样式即可

.loading-bar {
  position: relative;
  width: 500px;
  height: 30px;
  background-color: white;
  border-radius: 12px;
+ -webkit-box-reflect: below 1px linear-gradient(transparent, #0005);
}

效果如下:

image.png

该样式有兼容性问题,不建议在生产环境使用该样式,这里只是为了方便而使用

Non-standard:  This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

The -webkit-box-reflect CSS property lets you reflect the content of an element in one specific direction.

@keyframes定义并使用流动动画

要让loading bar动起来,就需要定义一个动画,我们可以通过改变background-position,也就是背景的位置来实现流动的效果

动画关键帧的定义如下

@keyframes flow {
  0% {
    background-position: 0 0;
  }

  0% {
    background-position: 200% 0;
  }
}

然后分别给两个伪元素应用该动画即可

.loading-bar::before {
  content: "";
  position: absolute;
  inset: 0;
  /* 默认角度是从上到下,90deg 逆时针旋转后变成从左到右渐变 */
  background: linear-gradient(
    90deg,
    var(--gradient-color-1),
    var(--gradient-color-2),
    var(--gradient-color-3),
    var(--gradient-color-4),
    var(--gradient-color-1),
    var(--gradient-color-2),
    var(--gradient-color-3),
    var(--gradient-color-4),
    var(--gradient-color-1)
  );
  background-size: 200%;
  border-radius: 12px;
+ animation: flow 3s linear infinite;
}
/* 使用一个和 ::before 相同的 作为霓虹灯特效 */
.loading-bar::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    var(--gradient-color-1),
    var(--gradient-color-2),
    var(--gradient-color-3),
    var(--gradient-color-4),
    var(--gradient-color-1),
    var(--gradient-color-2),
    var(--gradient-color-3),
    var(--gradient-color-4),
    var(--gradient-color-1)
  );
  background-size: 200%;
  filter: blur(10px);
  border-radius: 12px;
+ animation: flow 3s linear infinite;
}

现在的效果就和开头的展示一样啦,是不是很酷炫呢!