一、简介
之前有做过渐变色边框的样式,然后某天刷抖🎵,看到某个老师在讲跑马灯的样式效果,于是就自己尝试实现一下跑马灯样式的边框,虽然这种样式并不常见(基本没卵用),其使用场景我至今没想到,但是它足够花里胡哨,玩的就是花活。CSS才是前端最难精通的技术,也是前端对于后端最大的技术难点。以后可不敢在简历上写精通、熟练CSS了,最多写个见过CSS就可以了。
经过一番实践,我实现了两种形态的跑马灯样式边框,其效果如下图所示。其主要使用的CSS属性有:overflow
、position
、transform
、 animation
、@keyframes
以及::after
和::before
等等。
案例效果:
二、具体代码
1、首尾不相连的跑马灯边框
实现思路:
border
属性本身肯定是实现不了跑马灯的效果,因为其不能变化。因此我们就要想别的办法来实现边框的样式。实现方法:
① 利用padding
属性使元素的内容区域与最外层之间形成一个间隔。
② 利用伪元素::after
和position
,将该伪元素模拟为元素的内容区域,并设置背景颜色和圆角等样式,此时我们就实现了一个有透明边框的元素了,padding
区域就是边框区域。
③ 利用伪元素::before
定义一个具有渐变色背景的伪元素,然后通过动画使其围绕元素的中心点旋转。该伪元素的渐变背景决定了跑马灯边框的颜色。
④设置元素的overflow: hidden;
,隐藏伪元素::before
在旋转时,超出元素的部分,并通过设置层级,使伪元素::after
覆盖在伪元素::before
之上。这样旋转的伪元素::before
就只能在padding
区域内显示出来,也就是将其模拟成边框的效果,再加上旋转动画,从而显示出跑马灯边框的效果。
具体代码:
<style>
/* 定义一个全局的css变量 该宽度决定了边框的宽度 */
:root {
--border-width: 5px;
}
/* 定义盒子区域的宽高 包含边框所占区域 */
.d1 {
position: relative;
width: 200px;
height: 60px;
/* 为了让内容区域不被边框覆盖 设置等宽的padding */
padding: var(--border-width);
margin: 200px auto;
/* 设置元素圆角 */
border-radius: 10px;
text-align: center;
line-height: 60px;
color: #333;
/* 隐藏超出的部分 这很重要 */
overflow: hidden;
}
/* 利用伪元素::after 定义盒子内容区域 */
.d1::after {
content: '';
position: absolute;
/* 使用css变量定位内容区域位置 */
left: var(--border-width);
top: var(--border-width);
/* 根据css变量设置内容区域的宽高 */
width: calc(100% - var(--border-width) * 2);
height: calc(100% - var(--border-width) * 2);
background: #ccc;
/* 设置元素层级小于父级元素 使父元素的内容能够显示在该内容区域之上 */
z-index: -1;
/* 设置圆角 要比父元素的圆角小一些 */
border-radius: 6px;
}
/* 利用伪元素::before 定义盒子边框区域 */
.d1::before {
content: '';
position: absolute;
/* 利用定位将元素的左上角定位到父元素的中心 */
left: 50%;
top: 50%;
/* 设置该元素的宽高 要大于父元素的宽高 */
width: 220px;
height: 220px;
/* 设置该元素的渐变背景 */
background: linear-gradient(90deg, #000, yellow 20%);
/* 设置该元素的层级 要小于用伪元素::after 定义的盒子内容区域 */
z-index: -2;
/* 利用动画旋转该元素 */
animation: rotate1 1.3s linear infinite;
/* 定义旋转的圆心为元素的左上角 */
transform-origin: 0 0;
}
/* 声明旋转动画 */
@keyframes rotate1 {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
<!-- 跑马灯边框的根元素 -->
<div class="d1">跑马灯边框1</div>
页面效果:
为了帮助理解,去除掉overflow: hidden
属性的效果图:
2、首尾相连的跑马灯边框
实现思路:
其实该样式的实现思路与前面的基本相同,只不过是修改了边框元素的位置和旋转的中心点,使其能够在旋转动的过程中,覆盖边框的所有区域,从而使跑马灯首尾相连。实现方法:
① 利用padding
属性使元素的内容区域与最外层之间形成一个间隔。
② 利用伪元素::after
和position
,将该伪元素模拟为元素的内容区域,并设置背景颜色和圆角等样式,此时我们就实现了一个有透明边框的元素了,padding
区域就是边框区域。
③ 利用伪元素::before
定义一个具有渐变色背景的伪元素,先通过position
和transform
使该伪元素的中心点与根元素的中心点对齐,然后通过动画使其围绕元素的中心点旋转。同时该伪元素的渐变背景决定了跑马灯边框的颜色。
④设置元素的overflow: hidden;
,隐藏伪元素::before
在旋转时,超出元素的部分,并通过设置层级,使伪元素::after
覆盖在伪元素::before
之上。这样旋转的伪元素::before
就只能在padding
区域内显示出来,也就是将其模拟成边框的效果,再加上旋转动画,从而显示出跑马灯边框的效果。
具体代码:
<style>
/* 定义一个全局的css变量 该宽度决定了边框的宽度 */
:root {
--border-width: 5px;
}
/* 定义盒子区域的宽高 包含边框所占区域 */
.d2 {
position: relative;
width: 200px;
height: 60px;
/* 为了让内容区域不被边框覆盖 设置等宽的padding */
padding: var(--border-width);
margin: 200px auto;
/* 设置元素圆角 */
border-radius: 10px;
text-align: center;
line-height: 60px;
color: #333;
/* 隐藏超出的部分 这很重要 */
overflow: hidden;
}
/* 利用伪元素::after 定义盒子内容区域 */
.d2::after {
content: '';
position: absolute;
/* 使用css变量定位内容区域位置 */
left: var(--border-width);
top: var(--border-width);
/* 根据css变量设置内容区域的宽高 */
width: calc(100% - var(--border-width) * 2);
height: calc(100% - var(--border-width) * 2);
background: #ccc;
/* 设置元素层级小于父级元素 使父元素的内容能够显示在该内容区域之上 */
z-index: -1;
/* 设置圆角 要比父元素的圆角小一些 */
border-radius: 6px;
}
/* 利用伪元素::before 定义盒子边框区域 */
.d2::before {
content: '';
position: absolute;
/* 利用定位和位移将元素的中心点定位到父元素的中心点 */
left: 50%;
top: 50%;
transform: translateY(-50%) translateX(-50%);
width: 220px;
height: 220px;
/* 设置该元素的渐变背景 该背景决定了跑马灯边框的颜色 */
background: linear-gradient(-45deg, #000, yellow 60%);
/* 设置该元素的层级 要小于用伪元素::after 定义的盒子内容区域 */
z-index: -2;
/* 利用动画旋转该元素 */
animation: rotate2 1.5s linear infinite;
/* 设置旋转的圆心为元素的中心点 */
transform-origin: 50% 50%;
}
/* 声明旋转动画 旋转的同时 保持元素位置不变 */
@keyframes rotate2 {
0% {
transform: translateY(-50%) translateX(-50%) rotate(0deg);
}
100% {
transform: translateY(-50%) translateX(-50%) rotate(360deg);
}
}
</style>
<!-- 跑马灯边框的根元素 -->
<div class="d2">跑马灯边框2</div>
页面效果:
为了帮助理解,去除掉overflow: hidden
属性的效果图: