纯CSS实现一个M效果的动态线性边框

746 阅读2分钟

使用纯CSS实现一个M效果的动态线性边框效果,重点在控制关键帧动画的时间,让线条达到有一个停滞的效果,让下一个元素的动画开始执行。

line2.gif

先来四个div元素,并设置好基础样式

<div class="box">
    <div class="element">
      <span class="content">
        <span class="text">L</span>
      </span>
    </div>
    <div class="element">
      <span class="content">
        <span class="text">O</span>
      </span>
    </div>
    <div class="element">
      <span class="content">
        <span class="text">V</span>
      </span>
    </div>
    <div class="element">
      <span class="content">
        <span class="text">E</span>
      </span>
    </div>
</div>

* {
  box-sizing: border-box;
}
body {
  margin: 0;
  padding: 0;
  display: flex;
  min-height: 100vh;
  align-items: center;
  justify-content: center;
  background-color: #222;
}

.box {
  position: relative;
  display: flex;
  gap: 40x;
}

.box .element {
  position: relative;
  width: 100px;
  height: 100px;
  display: block;
  transform: rotate(315deg);
}
.box .element .content {
  display: flex;
  inset: 30px;
  align-items: center;
  justify-content: center;
  inset: 20px;
  position: absolute;
  background-color: #685752;

}
.box .element .content .text {
  color: #fff;
  font-weight: normal;
  transform: rotate(45deg);
  font-size: 2em;
}

效果如下

image.png 可能有人会问,为什么一个元素要包裹多层?

element负责旋转这个元素块,content设置了inset:20px,目的是为了在content上设置背景元素,可见的元素比实际元素少20px,这样线条看起来才离content元素有20px的距离。最后的text元素就是用来单纯包裹文本内容的,由于element发生了315度,所有要设置text的旋转角度为45度,才能将文本内容回正方向。

在伪元素上面设置线条

.box .element::before {
  content: '';
  position: absolute;
  width:100%;
  right: 0;
  height: 2px;
  background-image: linear-gradient(90deg, transparent, greenyellow);
}
.box .element::after {
  content: '';
  position: absolute;
  width:2px;
  right: 0;
  height: 100%;
  background-image: linear-gradient(180deg, transparent, greenyellow);

}

效果如下

image.png

为每个元素添加基于自定义CSS变量--i的延迟,创造出错位的动画效果,其次要使用translate设置好元素的位置,用于设置动画时产生移动效果。最后定义动画,结合CSS变量设置动画延迟。

在每个元素上设置CSS变量

<div class="box">
    <div class="element" style="--i: 0">
      <span class="content">
        <span class="text">L</span>
      </span>
    </div>
    <div class="element" style="--i: 1">
      <span class="content">
        <span class="text">O</span>
      </span>
    </div>
    <div class="element" style="--i: 2">
      <span class="content">
        <span class="text">V</span>
      </span>
    </div>
    <div class="element" style="--i: 3">
      <span class="content">
        <span class="text">E</span>
      </span>
    </div>
  </div>

定义动画

.box .element::before {
  content: '';
  position: absolute;
  width:100%;
  right: 0;
  height: 2px;
  background-image: linear-gradient(90deg, transparent, greenyellow);
  transform: translateX(-100%);
  animation: animateBefore 4s linear infinite;
  animation-delay: calc(1s * var(--i));
}
.box .element::after {
  content: '';
  position: absolute;
  width:2px;
  right: 0;
  height: 100%;
  background-image: linear-gradient(180deg, transparent, greenyellow);
  transform: translateY(-100%);
  animation: animateAfter 4s linear infinite;
  animation-delay: calc(1s * var(--i));
}

@keyframes animateBefore {
  0% {
      transform: translateX(-100%);
  }
  20%, 100% {
      transform: translateX(100%)
  }
}
@keyframes animateAfter {
  0%,12.5% {
      transform: translateY(-100%);
  }
  37.5%, 100% {
      transform: translateY(100%)
  }
}

效果如下

line.gif

最后我们将element元素设置溢出隐藏就ok啦

line2.gif

源码如下