3-dot loader with animated background gradient
by PhilQ
HTML
<div class="wrapper">
<div class="animate-bg-gradient cut-out-dots2">
<!-- <div class="circle"></div> -->
<!-- <div class="circle"></div> -->
<!-- <div class="circle"></div> -->
</div>
</div>
CSS
html, body { width: 100%; height: 100%; margin: 0; padding: 0; }
body {
display: flex;
align-items: center;
justify-content: center;
}
.wrapper {
border: 0px solid red;
}
.animate-bg-gradient {
--color1: #ccc;
--color2: #3e78cf;
--nr-dots: 3;
--dot-size: 20;
--space-in-dots: 0.5;
--width-in-dots: calc(var(--nr-dots) + (var(--nr-dots) - 1) * var(--space-in-dots));
--mask-width-in-element-percentage: calc((1 + var(--space-in-dots)) * (100% / var(--width-in-dots)));
--mask-100-in-dots: calc(var(--width-in-dots) - (1 + var(--space-in-dots)));
--shift-left-in-mask-position-percentage: calc(-100% * 0.5 * var(--space-in-dots) / var(--mask-100-in-dots));
--antialias-width: 1;
--antialias-percentage: calc(var(--antialias-width) / (0.5 * var(--dot-size)));
--antialias-edge-percentage: calc(100% * (1 - var(--antialias-percentage)));
height: calc(var(--dot-size) * 1px);
width: calc(var(--dot-size) * var(--width-in-dots) * 1px);
background-image: linear-gradient(
to right,
var(--color1),
var(--color1),
/**/
var(--color2),
var(--color2),
/**/
var(--color1),
var(--color1),
var(--color1),
var(--color1)
);
/* background x size = (nr_of_colorstops - 1) * 100% */
background-size: 700% 100%;
background-position: 0 0;
background-repeat: no-repeat;
animation: bg-scroll 2s linear infinite;
}
.cut-out-dots2 {
/*
The element contains 3 dots with a half-dot spacing in between them.
So, the element should be:
height: dot_size
width: dot_size * (nr_of_dots + (nr_of_dots - 1) * 0.5)
The dots are black circles (`radial-gradient`) in a repeating `mask-image`, being used as an alpha mask.
*/
-webkit-mask-mode: alpha;
-webkit-mask-repeat: repeat-x;
/*
The mask-image should repeat after 1.5 * dot_size (dot + spacing).
So, one mask-image width is:
1.5 * (100% / (nr_of_dots + (nr_of_dots - 1) * 0.5))
In this case:
1.5 * (100% / 4) = 37.5%
So, the mask-image size is:
height: 100%
width:...