Skip to content Skip to sidebar Skip to footer

Ring-shaped Process Spinner With Fading Gradient Effect Around The Ring

I want to create a ring-shaped process spinner with CSS3 or JavaScript, similar to the loading progress spinner in Android. The spinner should rotate continuously and be filled wit

Solution 1:

This would be trivially easy if only CSS or SVG had conical gradients! Until the conic-gradient() notation matures and gains support, we can approximate the effect by slicing up the gradient and covering the seams somehow.

Below you will find two solutions. The first solution uses an embedded SVG image; the second uses multiple CSS gradients and pseudo-elements.

Both start with a single div with a keyframe animation applied to make it rotate:

HTML:

<divclass="spinner"></div>

CSS:

@keyframes rotate {
    from { transform: rotate(0deg);   }
    to   { transform: rotate(360deg); }
}

.spinner {
    animation: rotate 1s linear infinite;
    height: 200px;
    width: 200px;
}

You can use a progress element if you prefer, but you will find it a pain to style. Also note that unless you're using something like prefixfree.js, you'll need to add the vendor-prefixed versions of the @keyframes at-rule and the transform and animation properties.


The SVG solution

@keyframes rotate {
    from { transform: rotate(0deg);   }
    to   { transform: rotate(360deg); }
}

.spinner {
    animation: rotate 1s linear infinite;
    background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwLDAgMjAwLDIwMCI+PGRlZnM+PGNsaXBQYXRoIGlkPSJyaW5nIj48cGF0aCBkPSJNMjAwLDEwMEExMDAsMTAwLDAsMSwxLDE5Ny44MSw3OS4yMUwxODguMDMsODEuMjlBOTAsOTAsMCwxLDAsMTkwLDEwMHoiLz48L2NsaXBQYXRoPjxmaWx0ZXIgaWQ9ImJsdXIiIHg9IjAiIHk9IjAiPjxmZUdhdXNzaWFuQmx1ciBpbj0iU291cmNlR3JhcGhpYyIgc3RkRGV2aWF0aW9uPSIzIiAvPjwvZmlsdGVyPjxwYXRoIGlkPSJwIiBkPSJNMjUwLDEwMEExNTAsMTUwLDAsMCwxLDI0Ni43MiwxMzEuMTlMMTAwLDEwMEEwLDAsMCwwLDAsMTAwLDEwMHoiIGZpbGw9ImN5YW4iLz48L2RlZnM+PGcgY2xpcC1wYXRoPSJ1cmwoI3JpbmcpIj48ZyBmaWx0ZXI9InVybCgjYmx1cikiIHRyYW5zZm9ybT0icm90YXRlKC02IDEwMCAxMDApIj48dXNlIHhsaW5rOmhyZWY9IiNwIiBmaWxsLW9wYWNpdHk9IjAiIHRyYW5zZm9ybT0icm90YXRlKDAgMTAwIDEwMCkiLz48dXNlIHhsaW5rOmhyZWY9IiNwIiBmaWxsLW9wYWNpdHk9Ii4wMyIgdHJhbnNmb3JtPSJyb3RhdGUoMTIgMTAwIDEwMCkiLz48dXNlIHhsaW5rOmhyZWY9IiNwIiBmaWxsLW9wYWNpdHk9Ii4wNyIgdHJhbnNmb3JtPSJyb3RhdGUoMjQgMTAwIDEwMCkiLz48dXNlIHhsaW5rOmhyZWY9IiNwIiBmaWxsLW9wYWNpdHk9Ii4xIiB0cmFuc2Zvcm09InJvdGF0ZSgzNiAxMDAgMTAwKSIvPjx1c2UgeGxpbms6aHJlZj0iI3AiIGZpbGwtb3BhY2l0eT0iLjE0IiB0cmFuc2Zvcm09InJvdGF0ZSg0OCAxMDAgMTAwKSIvPjx1c2UgeGxpbms6aHJlZj0iI3AiIGZpbGwtb3BhY2l0eT0iLjE3IiB0cmFuc2Zvcm09InJvdGF0ZSg2MCAxMDAgMTAwKSIvPjx1c2UgeGxpbms6aHJlZj0iI3AiIGZpbGwtb3BhY2l0eT0iLjIiIHRyYW5zZm9ybT0icm90YXRlKDcyIDEwMCAxMDApIi8+PHVzZSB4bGluazpocmVmPSIjcCIgZmlsbC1vcGFjaXR5PSIuMjQiIHRyYW5zZm9ybT0icm90YXRlKDg0IDEwMCAxMDApIi8+PHVzZSB4bGluazpocmVmPSIjcCIgZmlsbC1vcGFjaXR5PSIuMjgiIHRyYW5zZm9ybT0icm90YXRlKDk2IDEwMCAxMDApIi8+PHVzZSB4bGluazpocmVmPSIjcCIgZmlsbC1vcGFjaXR5PSIuMzEiIHRyYW5zZm9ybT0icm90YXRlKDEwOCAxMDAgMTAwKSIvPjx1c2UgeGxpbms6aHJlZj0iI3AiIGZpbGwtb3BhY2l0eT0iLjM0IiB0cmFuc2Zvcm09InJvdGF0ZSgxMjAgMTAwIDEwMCkiLz48dXNlIHhsaW5rOmhyZWY9IiNwIiBmaWxsLW9wYWNpdHk9Ii4zOCIgdHJhbnNmb3JtPSJyb3RhdGUoMTMyIDEwMCAxMDApIi8+PHVzZSB4bGluazpocmVmPSIjcCIgZmlsbC1vcGFjaXR5PSIuNDEiIHRyYW5zZm9ybT0icm90YXRlKDE0NCAxMDAgMTAwKSIvPjx1c2UgeGxpbms6aHJlZj0iI3AiIGZpbGwtb3BhY2l0eT0iLjQ1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTYgMTAwIDEwMCkiLz48dXNlIHhsaW5rOmhyZWY9IiNwIiBmaWxsLW9wYWNpdHk9Ii40OCIgdHJhbnNmb3JtPSJyb3RhdGUoMTY4IDEwMCAxMDApIi8+PHVzZSB4bGluazpocmVmPSIjcCIgZmlsbC1vcGFjaXR5PSIuNTIiIHRyYW5zZm9ybT0icm90YXRlKDE4MCAxMDAgMTAwKSIvPjx1c2UgeGxpbms6aHJlZj0iI3AiIGZpbGwtb3BhY2l0eT0iLjU1IiB0cmFuc2Zvcm09InJvdGF0ZSgxOTIgMTAwIDEwMCkiLz48dXNlIHhsaW5rOmhyZWY9IiNwIiBmaWxsLW9wYWNpdHk9Ii41OSIgdHJhbnNmb3JtPSJyb3RhdGUoMjA0IDEwMCAxMDApIi8+PHVzZSB4bGluazpocmVmPSIjcCIgZmlsbC1vcGFjaXR5PSIuNjIiIHRyYW5zZm9ybT0icm90YXRlKDIxNiAxMDAgMTAwKSIvPjx1c2UgeGxpbms6aHJlZj0iI3AiIGZpbGwtb3BhY2l0eT0iLjY2IiB0cmFuc2Zvcm09InJvdGF0ZSgyMjggMTAwIDEwMCkiLz48dXNlIHhsaW5rOmhyZWY9IiNwIiBmaWxsLW9wYWNpdHk9Ii42OSIgdHJhbnNmb3JtPSJyb3RhdGUoMjQwIDEwMCAxMDApIi8+PHVzZSB4bGluazpocmVmPSIjcCIgZmlsbC1vcGFjaXR5PSIuNyIgdHJhbnNmb3JtPSJyb3RhdGUoMjUyIDEwMCAxMDApIi8+PHVzZSB4bGluazpocmVmPSIjcCIgZmlsbC1vcGFjaXR5PSIuNzIiIHRyYW5zZm9ybT0icm90YXRlKDI2NCAxMDAgMTAwKSIvPjx1c2UgeGxpbms6aHJlZj0iI3AiIGZpbGwtb3BhY2l0eT0iLjc2IiB0cmFuc2Zvcm09InJvdGF0ZSgyNzYgMTAwIDEwMCkiLz48dXNlIHhsaW5rOmhyZWY9IiNwIiBmaWxsLW9wYWNpdHk9Ii43OSIgdHJhbnNmb3JtPSJyb3RhdGUoMjg4IDEwMCAxMDApIi8+PHVzZSB4bGluazpocmVmPSIjcCIgZmlsbC1vcGFjaXR5PSIuODMiIHRyYW5zZm9ybT0icm90YXRlKDMwMCAxMDAgMTAwKSIvPjx1c2UgeGxpbms6aHJlZj0iI3AiIGZpbGwtb3BhY2l0eT0iLjg2IiB0cmFuc2Zvcm09InJvdGF0ZSgzMTIgMTAwIDEwMCkiLz48dXNlIHhsaW5rOmhyZWY9IiNwIiBmaWxsLW9wYWNpdHk9Ii45MyIgdHJhbnNmb3JtPSJyb3RhdGUoMzI0IDEwMCAxMDApIi8+PHVzZSB4bGluazpocmVmPSIjcCIgZmlsbC1vcGFjaXR5PSIuOTciIHRyYW5zZm9ybT0icm90YXRlKDMzNiAxMDAgMTAwKSIvPjx1c2UgeGxpbms6aHJlZj0iI3AiIGZpbGwtb3BhY2l0eT0iMSIgdHJhbnNmb3JtPSJyb3RhdGUoMzQ4IDEwMCAxMDApIi8+PC9nPjwvZz48L3N2Zz4=') no-repeat;
    height: 200px;
    width: 200px;
}
<divclass="spinner"></div>

Tested and working in IE 10, Chrome and Firefox.

Caveats

Changing the inner or outer radius of the ring is more painful than you might imagine, as it would require editing the clip path values. It's outside the scope of this answer to explain how to calculate it, but suffice to say it took a bit of geometry. I'll try to put a generator on GitHub if I get time.

How the SVG version works

That big blob of gibberish is just a Base64 encoded SVG image. Run it through a Base64 decoder and you'll see the original SVG image.

Here's the full image nicely indented and commented so you can see exactly how it works:

<svgxmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink"viewBox="0,0 200,200"><defs><!-- Ring shape centred on 100, 100 with inner radius 90px, outer
             radius 100px and a 12 degree gap at 348. --><clipPathid="ring"><pathd="M 200, 100
                     A 100, 100, 0, 1, 1, 197.81, 79.21
                     L 188.03, 81.29
                     A 90, 90, 0, 1, 0, 190, 100 z"/></clipPath><!-- Very simple Gaussian blur, used to visually merge sectors. --><filterid="blur"x="0"y="0"><feGaussianBlurin="SourceGraphic"stdDeviation="3" /></filter><!-- A 12 degree sector extending to 150px. --><pathid="p"d="M 250, 100
                        A 150, 150, 0, 0, 1, 246.72, 131.19
                        L 100, 100
                        A 0, 0, 0, 0, 0, 100, 100 z"fill="cyan"/></defs><!-- Clip the blurred sectors to the ring shape. --><gclip-path="url(#ring)"><!-- Blur the sectors together to make a smooth shape and rotate
             them anti-clockwise by 6 degrees to hide the seam where the
             fully opaque sector blurs with the fully transparent one. --><gfilter="url(#blur)"transform="rotate(-6 100 100)"><!-- Each successive sector increases in opacity and is rotated
                 by a further 12 degrees. --><usexlink:href="#p"fill-opacity="0"transform="rotate(  0 100 100)"/><usexlink:href="#p"fill-opacity="0.03"transform="rotate( 12 100 100)"/><usexlink:href="#p"fill-opacity="0.07"transform="rotate( 24 100 100)"/><usexlink:href="#p"fill-opacity="0.1"transform="rotate( 36 100 100)"/><usexlink:href="#p"fill-opacity="0.14"transform="rotate( 48 100 100)"/><usexlink:href="#p"fill-opacity="0.17"transform="rotate( 60 100 100)"/><usexlink:href="#p"fill-opacity="0.2"transform="rotate( 72 100 100)"/><usexlink:href="#p"fill-opacity="0.24"transform="rotate( 84 100 100)"/><usexlink:href="#p"fill-opacity="0.28"transform="rotate( 96 100 100)"/><usexlink:href="#p"fill-opacity="0.31"transform="rotate(108 100 100)"/><usexlink:href="#p"fill-opacity="0.34"transform="rotate(120 100 100)"/><usexlink:href="#p"fill-opacity="0.38"transform="rotate(132 100 100)"/><usexlink:href="#p"fill-opacity="0.41"transform="rotate(144 100 100)"/><usexlink:href="#p"fill-opacity="0.45"transform="rotate(156 100 100)"/><usexlink:href="#p"fill-opacity="0.48"transform="rotate(168 100 100)"/><usexlink:href="#p"fill-opacity="0.52"transform="rotate(180 100 100)"/><usexlink:href="#p"fill-opacity="0.55"transform="rotate(192 100 100)"/><usexlink:href="#p"fill-opacity="0.59"transform="rotate(204 100 100)"/><usexlink:href="#p"fill-opacity="0.62"transform="rotate(216 100 100)"/><usexlink:href="#p"fill-opacity="0.66"transform="rotate(228 100 100)"/><usexlink:href="#p"fill-opacity="0.69"transform="rotate(240 100 100)"/><usexlink:href="#p"fill-opacity="0.7"transform="rotate(252 100 100)"/><usexlink:href="#p"fill-opacity="0.72"transform="rotate(264 100 100)"/><usexlink:href="#p"fill-opacity="0.76"transform="rotate(276 100 100)"/><usexlink:href="#p"fill-opacity="0.79"transform="rotate(288 100 100)"/><usexlink:href="#p"fill-opacity="0.83"transform="rotate(300 100 100)"/><usexlink:href="#p"fill-opacity="0.86"transform="rotate(312 100 100)"/><usexlink:href="#p"fill-opacity="0.93"transform="rotate(324 100 100)"/><usexlink:href="#p"fill-opacity="0.97"transform="rotate(336 100 100)"/><usexlink:href="#p"fill-opacity="1"transform="rotate(348 100 100)"/></g></g></svg>

This is minified, Base64 encoded and used as an inline CSS background image. You may also serve it as a separate file if you prefer. Technically, it should be possible to embed the image without the Base64 encoding, but right now that only works in Chrome.


The pure CSS solution

This solution uses separate linear gradients in each quadrant and relies on visual similarity to cover up the seams. The ring shape is formed using pseudo-elements.

@keyframes rotate {
    from { transform: rotate(0deg);   }
    to   { transform: rotate(360deg); }
}

.spinner {
    animation: rotate 1s linear infinite;
    background: cyan;
    border-radius: 50%;
    height: 200px;
    width: 200px;
    position: relative;
}

.spinner::before,
.spinner::after {
    content: '';
    position: absolute;
}

.spinner::before {
    border-radius: 50%;
    background:
        linear-gradient(0deg,   hsla(0, 0%, 100%, 1  ) 50%, hsla(0, 0%, 100%, 0.9) 100%)   0%0%,
        linear-gradient(90deg,  hsla(0, 0%, 100%, 0.9)  0%, hsla(0, 0%, 100%, 0.6) 100%) 100%0%,
        linear-gradient(180deg, hsla(0, 0%, 100%, 0.6)  0%, hsla(0, 0%, 100%, 0.3) 100%) 100%100%,
        linear-gradient(360deg, hsla(0, 0%, 100%, 0.3)  0%, hsla(0, 0%, 100%, 0  ) 100%)   0%100%
    ;
    background-repeat: no-repeat;
    background-size: 50%50%;
    top: -1px;
    bottom: -1px;
    left: -1px;
    right: -1px;
}

.spinner::after {
    background: white;
    border-radius: 50%;
    top: 3%;
    bottom: 3%;
    left: 3%;
    right: 3%;
}
<divclass="spinner"></div>

Tested and working in IE 10, Chrome and Firefox.

Caveats

Unlike the SVG solution, this only works against a solid background colour. It also requires modification in several places if you want to change that colour, which is a pain.

How the pure CSS version works

  1. To start with, the spinner is styled as a circle with a uniform background colour. This will be the colour of the spinning gradient.

    .spinner {
        background: cyan;
        border-radius: 50%;
        /* ... */
    }
    
  2. Set things up so that we can overlay the pseudo-elements on top of the spinner:

    .spinner {
        /* ... */position: relative;
    }
    
    .spinner::before,
    .spinner::after {
        content: '';
        position: absolute;
    }
    
  3. This is the tricky bit. Each quadrant of the :before pseudo-element is set to a different linear gradient starting with opaque white and progressively becoming more and more transparent. Towards the centre it's easy to see where the gradients join up, but notice how around the outside the colours are close enough together that they appear to join up smoothly.

    .spinner::before {
        border-radius: 50%;
        background:
            linear-gradient(0deg,   hsla(0, 0%, 100%, 1  ) 50%, hsla(0, 0%, 100%, 0.9) 100%)   0%0%,
            linear-gradient(90deg,  hsla(0, 0%, 100%, 0.9)  0%, hsla(0, 0%, 100%, 0.6) 100%) 100%0%,
            linear-gradient(180deg, hsla(0, 0%, 100%, 0.6)  0%, hsla(0, 0%, 100%, 0.3) 100%) 100%100%,
            linear-gradient(360deg, hsla(0, 0%, 100%, 0.3)  0%, hsla(0, 0%, 100%, 0  ) 100%)   0%100%
        ;
        background-repeat: no-repeat;
        background-size: 50%50%;
        top: -1px;
        bottom: -1px;
        left: -1px;
        right: -1px;
    }
    

    This is positioned so that it goes slightly over the edge of the spinner because if we position it right to the edge a faint rim of the background colour is visible.

  4. Finally, hide the middle bit using the ::after pseudo-element to make a ring shape:

    .spinner::after {
        background: white;
        border-radius: 50%;
        top: 3%;
        bottom: 3%;
        left: 3%;
        right: 3%;
    }
    

Et voilá!

Solution 2:

We can easily create this with only single div.

.loader {
  --border-width: 10px;
  
  height: 200px;
  width: 200px;
  border-radius: 50%;
  
  /* 0.5px's are needed to avoid hard-stopping */--mask: radial-gradient(
    farthest-side, 
    transparent calc(100% - var(--border-width) - 0.5px), 
    #000calc(100% - var(--border-width) + 0.5px)
  );
  -webkit-mask: var(--mask);
          mask: var(--mask);
          
  /* we're using two half linear-gradient which is masked by the radial-gradient */background: linear-gradient(to top, rgba(0,255,226, 1), rgba(0,255,226, 0.5)) 100%0/50%100% no-repeat,
              linear-gradient(rgba(0,255,226, 0.5) 50%, transparent 95%) 00/50%100% no-repeat;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
<divclass="loader"></div>

And this is the comparison of my answer with @Jordan Gray's answer by setting background to body:

@Jordan Gray's answer:

body {
  background: pink;
}

@keyframes rotate {
    from { transform: rotate(0deg);   }
    to   { transform: rotate(360deg); }
}

.spinner {
    animation: rotate 1s linear infinite;
    background: cyan;
    border-radius: 50%;
    height: 200px;
    width: 200px;
    position: relative;
}

.spinner::before,
.spinner::after {
    content: '';
    position: absolute;
}

.spinner::before {
    border-radius: 50%;
    background:
        linear-gradient(0deg,   hsla(0, 0%, 100%, 1  ) 50%, hsla(0, 0%, 100%, 0.9) 100%)   0%0%,
        linear-gradient(90deg,  hsla(0, 0%, 100%, 0.9)  0%, hsla(0, 0%, 100%, 0.6) 100%) 100%0%,
        linear-gradient(180deg, hsla(0, 0%, 100%, 0.6)  0%, hsla(0, 0%, 100%, 0.3) 100%) 100%100%,
        linear-gradient(360deg, hsla(0, 0%, 100%, 0.3)  0%, hsla(0, 0%, 100%, 0  ) 100%)   0%100%
    ;
    background-repeat: no-repeat;
    background-size: 50%50%;
    top: -1px;
    bottom: -1px;
    left: -1px;
    right: -1px;
}

.spinner::after {
    background: white;
    border-radius: 50%;
    top: 3%;
    bottom: 3%;
    left: 3%;
    right: 3%;
}
<divclass="spinner"></div>

My answer:

body {
  background: pink;
}

.loader {
  --border-width: 10px;
  
  height: 200px;
  width: 200px;
  border-radius: 50%;
  
  /* 0.5px's are needed to avoid hard-stopping */--mask: radial-gradient(
    farthest-side, 
    transparent calc(100% - var(--border-width) - 0.5px), 
    #000calc(100% - var(--border-width) + 0.5px)
  );
  -webkit-mask: var(--mask);
          mask: var(--mask);
          
  /* we're using two half linear-gradient which is masked by the radial-gradient */background: linear-gradient(to top, rgba(0,255,226, 1), rgba(0,255,226, 0.5)) 100%0/50%100% no-repeat,
              linear-gradient(rgba(0,255,226, 0.5) 50%, transparent 95%) 00/50%100% no-repeat;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
<divclass="loader"></div>

Solution 3:

Using background-clip on single div:

div {
  margin: 0 auto;
  margin-top: 3rem;
}

.spnr {
  height: 100px;
  width: 100px;
  border-radius: 50%;
  border: 5px solid transparent;
  animation: spin 1s linear infinite;

  background: linear-gradient(white, white), conic-gradient(from 0.15turn, white, #00EBD3);
  background-origin: border-box;
  background-clip: content-box, border-box;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
<divclass="spnr"></div>

More variations:

:root {
  --wbg: linear-gradient(white, white)
}

div {
  display: inline-block;
  margin: 01rem;
  margin-top: 0.5rem;
}

.one {
  background: var(--wbg), conic-gradient(from 0.15turn, white, #00EBD3);
}

.two {
  background: var(--wbg), conic-gradient(from 0.15turn, white, white, #000BD3);
}

.three {
  background: var(--wbg), conic-gradient(from 0.15turn, white 0.0turn, white .04turn, black 0.49turn, black 0.5turn, white 0.50turn, white 0.55turn, black 0.99999turn);
}

.four {
  background: var(--wbg), conic-gradient(from 0.25turn, white 0.0turn, darkgreen, white, darkgreen, white, darkgreen, white, darkgreen, white);
}

.five {
  background: var(--wbg), conic-gradient(from 0.25turn, white 0.0turn, red 0.125turn, white 0.125turn, red .25turn, white .25turn, red 0.375turn, white .375turn, red 0.5turn, white .5turn, red 0.625turn, white .625turn, red 0.75turn, white .75turn, red 0.875turn, white .875turn, red 1turn, white 1turn);
  animation-duration: 2s;
}

.six {
  border-width: 15px;
  background: var(--wbg), conic-gradient(from 0.25turn, white 0.0turn, white .125turn, orange 0.125turn, orange .25turn, white .25turn, white .375turn, orange 0.375turn, orange 0.5turn, white .5turn, white.625turn, orange .625turn, orange 0.75turn, white .75turn, white 0.875turn, orange .875turn, orange 1turn, white 1turn);
  opacity: 0.7;
}

.spnr {
  height: 60px;
  width: 60px;
  border-radius: 50%;
  border: 5px solid transparent;
  animation: spin 1s linear infinite;
  background-origin: border-box;
  background-clip: content-box, border-box;
}

.six {
  animation: size 2s linear infinite alternate;
}

.five {
  animation-duration: 2s;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

@keyframes size {
  0% {
    transform: rotate(0deg) scale(0.2);
    border-width: 5px;
  }
  100% {
    border-width: 10px;
    transform: rotate(840deg) scale(1);
  }
}
<divclass="spnr one"></div><divclass="spnr two"></div><divclass="spnr three"></div><divclass="spnr four"></div><divclass="spnr five"></div><divclass="spnr six"></div>

Solution 4:

conic-gradient with mask and no complex values:

.ring {
  width: 150px; /* the size */padding: 8px; /* the border */background: #07e8d6; /* the color */
  aspect-ratio: 1;
  border-radius: 50%;
  -webkit-mask:
    conic-gradient(#0000,#000),
    linear-gradient(#00000) content-box;
  -webkit-mask-composite: source-out;
          mask-composite: subtract;
  box-sizing: border-box;
  animation:r 2s linear infinite;
}

@keyframes r {to{transform:rotate(1turn)}}


body {
 background:linear-gradient(90deg,pink,#fff);
}
<divclass="ring"></div>

Solution 5:

I was able to create a real, full circle, gradient spinner, with opacity, by using a linear gradient on two half circles, and aligning them. No JavaScript or CSS necessary.

<svgversion="1.1"width="24"height="24"viewBox="-1 -1 25 25"xmlns="http://www.w3.org/2000/svg"
><defs><linearGradientx1="0%"y1="0%"x2="100%"y2="0"id="gradient-1"><stopstop-color="red"offset="0%" /><stopstop-color="red"offset="63.1%"stop-opacity=".631" /><stopstop-color="red"offset="100%"stop-opacity=".5" /></linearGradient><linearGradientx1="0%"y1="0%"x2="100%"y2="0"id="gradient-2"><stopstop-color="red"offset="0%"stop-opacity=".5" /><stopstop-color="red"offset="63.1%"stop-opacity=".12" /><stopstop-color="red"offset="100%"stop-opacity="0" /></linearGradient></defs><gfill="none"><gtransform="translate(1 1)"><pathd="M 10.5 10.5 m -10.5 0a 10.5 10.5 0 1 0 21 0a"stroke="url(#gradient-1)"stroke-width="3"
            /><animateTransformattributeName="transform"type="rotate"from="0 10.5 10.5"to="360 10.5 10.5"dur="1s"repeatCount="indefinite"
            /></g><gtransform="translate(1 1)"><pathd="M 10.5 10.5 m -10.5 0a 10.5 10.5 0 1 0 21 0a"stroke="url(#gradient-2)"stroke-width="3"
            /><animateTransformattributeName="transform"type="rotate"from="-180 10.5 10.5"to="180 10.5 10.5"dur="1s"repeatCount="indefinite"
            /></g></g></svg>

Post a Comment for "Ring-shaped Process Spinner With Fading Gradient Effect Around The Ring"