效果展示
Demo代码
HTML
Document
CSS
html, body {
margin: 0;
height: 100%;
}
body {
display: flex;
justify-content: center;
align-items: center;
background: #263238;
}
section {
width: 650px;
height: 300px;
padding: 10px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
/* 红色边框仅作提示 */
border: 2px solid red;
}
span {
width: 80px;
height: 80px;
border-radius: 50%;
display: inline-block;
position: relative;
/* background-color: rebeccapurple; */
}
span::after {
content: '';
width: 32px;
height: 32px;
border-radius: 50%;
position: absolute;
left: 0;
/* background-color: red; */
transform: translate(-50%, 100%);
animation: loading 2s linear infinite;
top: 0;
}
@keyframes loading {
0% {
background: rgba(255, 255, 255, 1);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
}
14% {
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 1), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
}
28% {
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 1), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
}
42% {
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 1), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
}
57% {
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 1), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
}
71% {
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 1), 18px 32px 0 -6px rgba(255, 255, 255, 0);
}
85% {
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 1);
}
100% {
background: rgba(255, 255, 255, 0.5);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
}
}
原理详解
步骤1
使用span标签,设置
- 宽度、高度均为80px
- 背景色:黄色
- 圆角化
width: 80px;
height: 80px;
background-color: yellow;
border-radius: 50%;
效果图如下
步骤2
利用span::after,设置
- 绝对定位(left: 0)
- 宽度、高度均为32px
- 背景色:红色
- 圆角化
content: '';
width: 32px;
height: 32px;
border-radius: 50% ;
position: absolute;
left: 0;
效果图如下
步骤3
移动红色小球位置
/*向左移动自身50% 再右移自身100%的距离*/
transform: translate(-50%, 100%);
效果图如下
步骤4
使用span::after的阴影(box-shadow)充当白色小球
一共需要6个阴影
为6个小球定义位置 ,使之分布至黄色小球的四周
box-shadow:
18px -38px 0 -1px rgba(255, 255, 255, 1),
56px -38px 0 -2px rgba(255, 255, 255, 1),
78px -10px 0 -3px rgba(255, 255, 255, 1),
68px 20px 0 -4px rgba(255, 255, 255, 1),
44px 34px 0 -5px rgba(255, 255, 255, 1),
18px 32px 0 -6px rgba(255, 255, 255, 1);
效果图如下
步骤5
为这些小球添加动画
此时修改红色小球背景色为白色
大球四周就拥有7个白色小球(一个span:after 加上6个阴影产生的小球)
我们需要利用animation控制这7个小球的显示与否
每个小球的状态假设只有两种:显示与不显示
使用颜色对应两者状态
- 显示:rgba(255, 255, 255, 1)
- 不显示:rgba(255, 255, 255, 0)
每次只显示一个小球,那么7个小球就产生了7帧关键帧
在这里我们使用8帧,最后一帧颜色稍微浅一点(其实7帧也行,看个人喜好)
第一帧
background: rgba(255, 255, 255, 1);/*span:after的颜色*/
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
效果图如下
第二帧
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 1), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
效果图如下
第三帧
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 1), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
效果图如下
第四帧
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 1), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
效果图如下
第五帧
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 1), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
效果图如下
第六帧
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 1), 18px 32px 0 -6px rgba(255, 255, 255, 0);
效果图如下
第七帧
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 1);
效果图如下
第八帧
background: rgba(255, 255, 255, 0.5);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
效果图如下
步骤6
使用动画均匀过度这8帧
animation: loading 2s linear infinite;
@keyframes loading {
/*第一帧*/
0% {
background: rgba(255, 255, 255, 1);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
}
/*第二帧*/
14% {
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 1), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
}
/*第三帧*/
28% {
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 1), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
}
/*第四帧*/
42% {
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 1), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
}
/*第五帧*/
57% {
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 1), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
}
/*第六帧*/
71% {
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 1), 18px 32px 0 -6px rgba(255, 255, 255, 0);
}
/*第七帧*/
85% {
background: rgba(255, 255, 255, 0);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 1);
}
/*第八帧*/
100% {
background: rgba(255, 255, 255, 0.5);
box-shadow: 18px -38px 0 -1px rgba(255, 255, 255, 0), 56px -38px 0 -2px rgba(255, 255, 255, 0), 78px -10px 0 -3px rgba(255, 255, 255, 0), 68px 20px 0 -4px rgba(255, 255, 255, 0), 44px 34px 0 -5px rgba(255, 255, 255, 0), 18px 32px 0 -6px rgba(255, 255, 255, 0);
}
}
效果图如下
步骤7
取消span的背景色
/* background-color: yellow; */
最后效果图如下