最近在公众号里看到一篇如何只用 CSS 完成漂亮的加载的文章(下面统一称‘原文’),最后仿照它的源码撸一遍,感觉有些收获。因为这篇文章并没有给出太多的细节,所以我觉得有必要把有用的东西记录下来。
具体的实现在原文中已经有介绍,这里主要记录一下实现的原理。
布局:
<body>
<div class="logo">
<div class="white"></div>
<div class="orange"></div>
<div class="red"></div>
</div>
</body>
红色,橙色,白色区域对应red,orange,white样式的div。上边框和右边框对应伪元素before,下边框和左边框对应伪元素after。
动画效果利用@keyframes实现。@keyframes可以定义某属性在某段时间内的变化。对于红色和白色这里选择width,橙色选择height。边框的变化width和height属性都会用到。
确定变化属性之后,再来确定一下变化的顺序,在@keyframes可以指定不同的百分比来实现。首先统一所有的动画时间都是1.5s,然后将0%~100%的区间分5份:
0~25,25~50,50~65,65~80,80~100。分别对应before,after,red,orange,white的动画区间。
初始时候所有的width和height都是0,呈现一个空白的样子:
@keyframes border-before {
0%,
6%{
width: 0;
height: 0;
border-right-color: transparent;
border-top-color: transparent;
}
}
@keyframes border-after {
0%,
25%{
width: 0;
height: 0;
border-left-color: transparent;
border-bottom-color: transparent;
}
}
@keyframes red {
0%,
50%{
width: 0;
opacity: 0;
}
}
@keyframes orange {
0%,
65% {
height: 0;
opacity: 0;
}
}
@keyframes white {
0%,
80%{
width: 0;
opacity: 0;
}
}
before对应0%~6%,after对应0%~25%,red对应0%~50%,orange对应0%~65%,white对应0%~80%。
接下来是各个区域的变化:
before的变化在6%~25%,这个区间内,需要先展示top,再展示right,对应先width:0~100px,然后height:0~100px。于是:
@keyframes border-before {
0%,
6%{
width: 0;
height: 0;
border-right-color: transparent;
border-top-color: transparent;
}
//展示top
15%{
width: 100%;
height: 0;
border-top-color: black;
}
//展示right
25%,
100%{
width: 100%;
height: 100%;
border-right-color: black;
}
}
其他的也都一样,直接上代码:
@keyframes border-after {
0%,
25%{
width: 0;
height: 0;
border-left-color: transparent;
border-bottom-color: transparent;
}
25.01%{
border-left-color: transparent;
border-bottom-color: black;
}
35%{
width: 100%;
height: 0;
border-left-color: black;
}
50%,
100%{
width: 100%;
height: 100%;
}
}
@keyframes red {
0%,
50%{
width: 0;
opacity: 0;
}
50.01%{
opacity: 1
}
65%,
100%{
width: 27%;
opacity: 1;
}
}
@keyframes orange {
0%,
65% {
height: 0;
opacity: 0;
}
65.01% {
opacity: 1;
}
80%,
100% {
height: 50%;
opacity: 1;
}
}
@keyframes white {
0%,
80%{
width: 0;
opacity: 0;
}
80.01%{
opacity: 1
}
90%,
100%{
width: 27%;
opacity:1;
}
}
@keyframes 定义完之后,只需要在对应的class加上:
animation: orange 1.5s infinite;
orange对应我们定义的keyframes,第二个是动画时间,所有的都定义一样,最后一个表示无限循环。
到这里我们就实现了从上边框开始一直到最后白色区域出现的效果。可是怎么逆时针返回呢?
animation-direction: alternate;
上段的定义:
如果 animation-direction 值是 “alternate”,则动画会在奇数次数(1、3、5 等等)正常播放,而在偶数次数(2、4、6 等等)向后播放。
具体代码详见如何只用 CSS 完成漂亮的加载