Paulund

CSS Full Circle Of Circles

This is part of the CSS loader series that show different loaders that can be used in your application to show the user the app is processing and to please wait. CSS Loaders

In this tutorial we're going to create a circle made up of circles the animation will change the opacity on each of the smaller circles.

The HTML

The HTML for this CSS loader is just made up of one element, there are 8 inner circles so we can't use the same technique we've used in previous CSS loader tutorials we're going to have to do something different.


<div id="full-circle-circles"></div>

The CSS As this is just one DIV we need to style the main element, the only important property we need is the animation property using the circleTheCirlesSpin animation. Placing the border-radius at 50% will allow us to use the box-shadow property in later styling.


#full-circle-circles {
    margin: 2rem auto;
    width: 1em;
    height: 1em;
    border-radius: 50%;
    position: relative;
    animation: circleTheCirlesSpin 1.1s infinite ease;
}

The animation keyframes does all the hard work with this CSS loader, it has one HTML element but there are 8 circles on the page so we need to create these circles in a different way. We're going to use box-shadow to create the other circles, we can create an endless amount of box shadow elements where we can position them where ever we want and change the opacity on each of the elements. At different times in the animation we need to go through each shadow and change the opacity. Ideally this will be done using a Sass mixin but for now we can just outline these box shadows in plain CSS. To create the animation we're going to change the keyframes every 12.5% and all we're doing is move where the opacity is set.


@keyframes circleTheCirlesSpin {
    0%,
    100% {
        box-shadow: 0 -2.6rem 0 0 #333,
        1.8rem -1.8rem 0 0 rgba(0, 0, 0, 0.2),
        2.5rem 0 0 0 rgba(0, 0, 0, 0.2),
        1.75rem 1.75rem 0 0 rgba(0, 0, 0, 0.2),
        0 2.5rem 0 0 rgba(0, 0, 0, 0.2),
        -1.8rem 1.8rem 0 0 rgba(0, 0, 0, 0.2),
        -2.6rem 0 0 0 rgba(0, 0, 0, 0.5),
        -1.8rem -1.8rem 0 0 rgba(0, 0, 0, 0.7);
    }
    12.5% {
        box-shadow: 0 -2.6rem 0 0 rgba(0, 0, 0, 0.7),
        1.8rem -1.8rem 0 0 #333,
        2.5rem 0 0 0 rgba(0, 0, 0, 0.2),
        1.75rem 1.75rem 0 0 rgba(0, 0, 0, 0.2),
        0 2.5rem 0 0 rgba(0, 0, 0, 0.2),
        -1.8rem 1.8rem 0 0 rgba(0, 0, 0, 0.2),
        -2.6rem 0 0 0 rgba(0, 0, 0, 0.2),
        -1.8rem -1.8rem 0 0 rgba(0, 0, 0, 0.5);
    }
    25% {
        box-shadow: 0 -2.6rem 0 0 rgba(0, 0, 0, 0.5),
        1.8rem -1.8rem 0 0 rgba(0, 0, 0, 0.7),
        2.5rem 0 0 0 #333,
        1.75rem 1.75rem 0 0 rgba(0, 0, 0, 0.2),
        0 2.5rem 0 0 rgba(0, 0, 0, 0.2),
        -1.8rem 1.8rem 0 0 rgba(0, 0, 0, 0.2),
        -2.6rem 0 0 0 rgba(0, 0, 0, 0.2),
        -1.8rem -1.8rem 0 0 rgba(0, 0, 0, 0.2);
    }
    37.5% {
        box-shadow: 0 -2.6rem 0 0 rgba(0, 0, 0, 0.2),
        1.8rem -1.8rem 0 0 rgba(0, 0, 0, 0.5),
        2.5rem 0 0 0 rgba(0, 0, 0, 0.7),
        1.75rem 1.75rem 0 0 #333,
        0 2.5rem 0 0 rgba(0, 0, 0, 0.2),
        -1.8rem 1.8rem 0 0 rgba(0, 0, 0, 0.2),
        -2.6rem 0 0 0 rgba(0, 0, 0, 0.2),
        -1.8rem -1.8rem 0 0 rgba(0, 0, 0, 0.2);
    }
    50% {
        box-shadow: 0 -2.6rem 0 0 rgba(0, 0, 0, 0.2),
        1.8rem -1.8rem 0 0 rgba(0, 0, 0, 0.2),
        2.5rem 0 0 0 rgba(0, 0, 0, 0.5),
        1.75rem 1.75rem 0 0 rgba(0, 0, 0, 0.7),
        0 2.5rem 0 0 #333,
        -1.8rem 1.8rem 0 0 rgba(0, 0, 0, 0.2),
        -2.6rem 0 0 0 rgba(0, 0, 0, 0.2),
        -1.8rem -1.8rem 0 0 rgba(0, 0, 0, 0.2);
    }
    62.5% {
        box-shadow: 0 -2.6rem 0 0 rgba(0, 0, 0, 0.2),
        1.8rem -1.8rem 0 0 rgba(0, 0, 0, 0.2),
        2.5rem 0 0 0 rgba(0, 0, 0, 0.2),
        1.75rem 1.75rem 0 0 rgba(0, 0, 0, 0.5),
        0 2.5rem 0 0 rgba(0, 0, 0, 0.7),
        -1.8rem 1.8rem 0 0 #333,
        -2.6rem 0 0 0 rgba(0, 0, 0, 0.2),
        -1.8rem -1.8rem 0 0 rgba(0, 0, 0, 0.2);
    }
    75% {
        box-shadow: 0 -2.6rem 0 0 rgba(0, 0, 0, 0.2),
        1.8rem -1.8rem 0 0 rgba(0, 0, 0, 0.2),
        2.5rem 0 0 0 rgba(0, 0, 0, 0.2),
        1.75rem 1.75rem 0 0 rgba(0, 0, 0, 0.2),
        0 2.5rem 0 0 rgba(0, 0, 0, 0.5),
        -1.8rem 1.8rem 0 0 rgba(0, 0, 0, 0.7),
        -2.6rem 0 0 0 #333,
        -1.8rem -1.8rem 0 0 rgba(0, 0, 0, 0.2);
    }
    87.5% {
        box-shadow: 0 -2.6rem 0 0 rgba(0, 0, 0, 0.2),
        1.8rem -1.8rem 0 0 rgba(0, 0, 0, 0.2),
        2.5rem 0 0 0 rgba(0, 0, 0, 0.2),
        1.75rem 1.75rem 0 0 rgba(0, 0, 0, 0.2),
        0 2.5rem 0 0 rgba(0, 0, 0, 0.2),
        -1.8rem 1.8rem 0 0 rgba(0, 0, 0, 0.5),
        -2.6rem 0 0 0 rgba(0, 0, 0, 0.7),
        -1.8rem -1.8rem 0 0 #333;
    }
}

View the demo to see this HTML and CSS in action.