只用html CSS3 画一个 circle spinner

352 查看

效果如下

这里只是介绍我的一个实现方案, 顺便留下一个没能解决的问题(重点), 求大神支招解决


HTML 结构

  <div class="spinner">
    <div class="top"></div>
    <div class="bottom"></div>
  </div>

解释:
0. 圆圈使用border和border-radius实现, 扇形通过rotate和overflow:hidden的方式来实现。
1. spinner 作为容器, top负责上半个圆, bottom负责下半个圆。

css frame

 .spinner {
        width: 70px;
        height: 70px;
        position: relative;
        left: 100px;
        top: 100px;
        color: white;
 }
 .spinner .top, .spinner .bottom{
        width: 70px;
        height: 35px;
        position: relative;
        overflow: hidden;
}

.spinner::before, .spinner .top::before, .spinner .bottom::before{
        content: '';
        width: 70px;
        height: 70px;
        display: inline-block;
        border-style: solid;
        border-top-color: #FFF;
        border-right-color: #FFF;
        border-left-color: transparent;
        border-bottom-color: transparent;
        border-radius: 50%;
        border-width: 5px;
        box-sizing: border-box;
}

动画部分css

 /* 使用spinner::before来覆盖空隙*/
    .spinner::before {
        position: absolute;
        border-right-color: transparent;
        border-top-color: transparent;
        transform: rotateZ(47deg);
        -webkit-animation: fix-gap 2s ease-in infinite;
    }

    .spinner .top::before {
        transform: rotateZ(-225deg);
        -webkit-animation: rotate-top 2s ease-in infinite;
        /*-webkit-animation-delay: 0.3s;*/
    }

    .spinner .bottom::before {
        border-bottom-color: #fff;
        border-top-color: transparent;
        position: relative;
        bottom: 35px;
        transform: rotateZ(-135deg);
        -webkit-animation: rotate-bottom 2s  ease-out infinite;
        /*-webkit-animation-delay: 0.3s;*/
    }

    @-webkit-keyframes fix-gap {
        49%  {
            border-top-color: transparent;
        }
        50% { 
            border-top-color: white;
        }

        100% { 
            border-top-color: white; 
        }
    }

    @-webkit-keyframes rotate-top {
        50% { 
            transform: rotateZ(-45deg); 
        }

        100% {  
            transform: rotateZ(-45deg); 
        }
    }

    @-webkit-keyframes rotate-bottom {
        50% { 
            transform: rotateZ(-135deg);
        }

        100% {  
            transform: rotateZ(45deg); 
        }
    }

解释:
这里用到了3个before伪元素,为什么会使用3个,不是只有上半个和下半个圆吗? 对, 这就是我要提出来的问题, 见下图:

可能没有发现问题, 如果你仔细些可以看到上半圆和下半圆中间有一条空隙, 不能忍啊!
见大图:

为了fix这条空隙, 我的解决方法是通过旋转spinner::before ,在动画过程中添加border的来覆盖空隙。

所有代码




<div class="spinner"> <div class="top"></div> <div class="bottom"></div> </div> <h4>Circle Spinner -by 横天</h4> <style> .spinner { width: 70px; height: 70px; position: relative; left: 100px; top: 100px; color: white; } .spinner .top, .spinner .bottom{ width: 70px; height: 35px; position: relative; -webkit-backface-visibility: hidden; -webkit-transform: translateZ(0) scale(1.0, 1.0); overflow: hidden; } .spinner::before, .spinner .top::before, .spinner .bottom::before{ content: ''; width: 70px; height: 70px; display: inline-block; border-style: solid; border-top-color: #FFF; border-right-color: #FFF; border-left-color: transparent; border-bottom-color: transparent; border-radius: 50%; border-width: 5px; box-sizing: border-box; } /* 使用spinner::before来覆盖空隙*/ .spinner::before { position: absolute; border-right-color: transparent; border-top-color: transparent; transform: rotateZ(47deg); -webkit-animation: fix-gap 2s ease-in infinite; } .spinner .top::before { transform: rotateZ(-225deg); -webkit-animation: rotate-top 2s ease-in infinite; /*-webkit-animation-delay: 0.3s;*/ } .spinner .bottom::before { border-bottom-color: #fff; border-top-color: transparent; position: relative; bottom: 35px; transform: rotateZ(-135deg); -webkit-animation: rotate-bottom 2s ease-out infinite; /*-webkit-animation-delay: 0.3s;*/ } @-webkit-keyframes fix-gap { 49% { border-top-color: transparent; } 50% { border-top-color: white; } 100% { border-top-color: white; } } @-webkit-keyframes rotate-top { 50% { transform: rotateZ(-45deg); } 100% { transform: rotateZ(-45deg); } } @-webkit-keyframes rotate-bottom { 50% { transform: rotateZ(-135deg); } 100% { transform: rotateZ(45deg); } } body { background: rgb(235, 205, 86); } h4 { position: absolute; bottom: 20px; left: 20px; margin: 0; font-weight: 200; opacity: .5; font-family: sans-serif; color: #fff; } </style>

最后

  1. 跪求更好的解决方法?
  2. 我已经试过了-webkit-backface-visibility: hidden; 或者 -webkit-transform: translateZ(0) scale(1.0, 1.0); 没有达到想要的效果, 求fix!!!!!
  3. 其实用svg + css3实现很简单, 但是svg在mobile 兼容性差, 所以只能用div + css3, 或者canvas。

补充

如果只是要画一个圆形, 可以用linear-gradient. 但是不支持transition

   <div class="circle"> </div>
   <style>
      .circle{
         background-image: linear-gradient(18deg, #57ad68 50%, transparent 50%, transparent), linear-gradient(270deg, #57ad68 50%, #b7b7b7 50%, #b7b7b7);
         width: 100px; 
         height: 100px;
         border-radius: 50%;
       }
   </style>