Is it possible to draw a partial circle outline in CSS (open ring shape)?

后端 未结 4 559
太阳男子
太阳男子 2020-12-08 20:00

I\'m interested in creating a loading spinner entirely in CSS but in order to do so I would need to be able to draw a open ring shape like this:

The ring wo

4条回答
  •  温柔的废话
    2020-12-08 20:45

    Static Image

    A simplified example that just relies on a single HTML element and CSS class might look like this :

    .arc {
      /* Border size and color */
      border: 2px solid #000;
      /* Creates a circle */
      border-radius: 50%;
      /* Circle size */
      height: 100px;
      width: 100px;
      /* Use transparent borders to define opening (more transparent = larger opening) */
      border-top-color: transparent;
      border-left-color: transparent;
      /* Use transform to rotate to adjust where opening appears */
      transform: rotate(300deg)
    }
    

    Example

    .arc {
      border: 2px solid #000;
      border-radius: 50%;
      height: 100px;
      width: 100px;
      border-top-color: transparent;
      transform: rotate(300deg)
    }

    Rotating Image

    You can apply a basic rotation to the previous static example by taking advantage of CSS-based animations using @keyframes :

    .arc {
      /* Border size and color */
      border: 2px solid #000;
      /* Creates a circle */
      border-radius: 50%;
      /* Circle size */
      height: 100px;
      width: 100px;
      /* Use transparent borders to define opening (more transparent = larger opening) */
      border-top-color: transparent;
      /* Rotate indefinitely (longer time = slower rotation) */
      animation: rotate 2s infinite linear;
    }
    
    @keyframes rotate {
      0%    { transform: rotate(0deg);  }
      100%  { transform: rotate(360deg);  }
    }
    

    Example

    .arc {
      border: 2px solid #000;
      border-radius: 50%;
      height: 100px;
      width: 100px;
      border-top-color: transparent;
      animation: rotate 2s infinite linear;
    }
    
    @keyframes rotate {
      0%    { transform: rotate(0deg);  }
      100%  { transform: rotate(360deg);  }
    }

    Drawing (without SVG)

    Another approach that I came across, while not nearly as elegant as the previous approaches does appear to achieve your desired effect. In involves the use of several animations as well as showing/hiding different sections of the circle as necessary.

    The code snippet contains an example demonstrating it.

    Example

    #container {
      position: absolute;
      width: 100px;
      height: 100px;
      animation: colors 1s infinite;
    }
    #halfclip {
      width: 50%;
      height: 100%;
      right: 0px;
      position: absolute;
      overflow: hidden;
      transform-origin: left center;
      animation: cliprotate 4s steps(2) infinite;
      -webkit-animation: cliprotate 4s steps(2) infinite;
    }
    .halfcircle {
      box-sizing: border-box;
      height: 100%;
      right: 0px;
      position: absolute;
      border: solid 2px transparent;
      border-top-color: #000;
      border-left-color: #000;
      border-radius: 50%;
    }
    #clipped {
      width: 200%;
      animation: rotate 2s linear infinite;
      -webkit-animation: rotate 2s linear infinite;
    }
    #fixed {
      width: 100%;
      transform: rotate(135deg);
      animation: showfixed 4s steps(2) infinite;
      -webkit-animation: showfixed 4s linear infinite;
    }
    @-webkit-keyframes cliprotate {
      0% {
        transform: rotate(0deg);
      }
      100% {
        transform: rotate(360deg);
      }
    }
    @keyframes cliprotate {
      0% {
        transform: rotate(0deg);
      }
      100% {
        transform: rotate(360deg);
      }
    }
    @-webkit-keyframes rotate {
      0% {
        transform: rotate(-45deg);
      }
      100% {
        transform: rotate(135deg);
      }
    }
    @keyframes rotate {
      0% {
        transform: rotate(-45deg);
      }
      100% {
        transform: rotate(135deg);
      }
    }
    @-webkit-keyframes showfixed {
      0% {
        opacity: 0;
      }
      49.9% {
        opacity: 0;
      }
      50% {
        opacity: 1;
      }
      100% {
        opacity: 1;
      }
    }

    Drawing (with SVG)

    Taking advantage of SVG is probably the best way to address this problem, as it's explicitly designed to handle drawing within the browser. I'd highly recommend that approach if SVG support is available.

    Dylan's response details what this implementation might look like.

提交回复
热议问题