前言
最近在做大屏的项目,其中一些数据卡片,需要添加一些边框动画
倒腾来,倒腾去,写了下面这两种效果
接下来我们来看下实现这种效果
实现
转动的边框线
我们先实现这个效果
创建项目文件夹
mkdir light-card
cd code-review
创建 single.html 并用 vscode 打开
cd .>single.html
code ./
修改下single.html,清除下默认样式,加一点背景
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
body {
background-color: black;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;;
}
</style>
</head>
<body>
</body>
</html>
接下来,我们实现一下这个卡片
添加body一个 div 作为卡片,并编写下简单的样式
边框线如何实现呢?
为了实现简单点,采用伪类去实现
.card::before, .card::after {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
border: 2px solid #ffffff;
transition: all .5s;
border-radius: 10px;
}
边框线有了,但不是一小一段的啊
这里就要采用一个神奇的 CSS属性 clip-path: inset(0 0 98% 0)
.card::before, .card::after {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
border: 2px solid #ffffff;
transition: all .5s;
border-radius: 10px;
clip-path: inset(0 0 98% 0);
}
clip-path 使用裁剪方式创建元素的可显示区域
inset 是定义一个矩形,四个参数分别为 上侧、右侧、下侧和左侧向内的偏移量
clip-path: inset(0 0 98% 0)就是将下侧 90% 剪切掉,也就是红框的部分
根据这个CSS属性,实现一个动画剪切动画,先保留上侧,依次是右侧、下侧,依次循环
但是只有一条线啊
那是因为before、after 伪类重叠在一起了
给 after 重新加一个比before动画慢一半再执行的动画就好了
流光边框
这样的动画是怎么实现的?
我们来看下这个动画的本质
相信你也大概猜出了,这个动画就是通过遮挡最后旋转元素来实现的
接下来我们来实现下吧
创建 single.html 文件,并加入基本样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
body {
background-color: black;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.card {
width: 220px;
height: 120px;
color: #ffffff;
text-align: center;
line-height: 100px;
font-size: 28px;
border-radius: 10px;
position: relative;
}
</style>
</head>
<body>
<div class="card">
流光边框
</div>
</body>
</html>
创建最主要的旋转元素,为了方便还是使用伪元素
.card::before {
content: '';
position: absolute;
left: -50%;
top: -50%;
width: 200%;
height: 200%;
border-radius: 10px;
background-image: conic-gradient(transparent, #ffffff, transparent 30%);
z-index: -2;
animation: rotation 4s linear infinite;
}
@keyframes rotation {
to {
transform: rotate(360deg);
}
}
采用 background-image 实现背景,且让元素绕中心旋转
z-index: 2 将旋转元素放到最后一层
把 .card 的背景颜色去掉,加上 overflow: hidden
最后,我们在这个两个元素的中间加一个黑色背景的元素,挡住里面的光
.card::after {
content: '';
position: absolute;
--g: 4px;
width: calc(100% - var(--g) * 2);
height: calc(100% - var(--g) * 2);
background: #000;
left: var(--g);
top: var(--g);
border-radius: inherit;
z-index: -1;
opacity: 0.9;
}
至此,两个动画我们都实现了
小结
第一个动画,采用 clip-path属性动态剪切边框来实现
第二个动画,采用 遮挡旋转元素来实现