Creating a Pie Timer Only Using CSS

Creating a pie timer using CSS is a good les­son in cre­at­ive use of pseudo-ele­ments and CSS anim­a­tions and the end res­ult can be used to replace a load­ing spin­ner. Let’s start by cre­atng our pie timer ele­ment (using a single ele­ment to be as semant­ic as pos­sible):

<div class="timer"></div>

Next, let’s get some basic CSS styles sor­ted, includ­ing set­ting the size of our pie timer and ensur­ing that it’s a circle:

.timer {
border-radius: 50%;
height: 6em;
width: 6em;
}

We can’t actu­ally see any­thing yet, so let’s add some col­our. We’re going to use a CSS gradi­ent to fill the left half of our pie timer with our primary col­our and the right half with our sec­ond­ary col­our.

.timer {
background: linear-gradient(90deg, #6c6 50%, #ddd 50%);
}

Now we need to cre­ate the pseudo-ele­ment that will act as a mask in the pie timer anim­a­tion. Let’s also set the timer element’s positon to rel­at­ive so that we can eas­ily pos­i­tion the mask in rela­tion to the pie timer:

As the mask will only be used to cov­er half of the pie timer, the width is set to 50% and we’re using border-radius to make the mask a semi­circle. A back­ground col­our has not been set as the mask anim­a­tion will take care of that.

Next we need to build our anim­a­tions. We’ll start with the easi­er of the two; the one that will spin the pie timer around. The key­frames are very straight­for­ward:

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

We don’t need to set any value at 0% as that’s the pos­i­tion the ele­ment is already in. Now we’re going to use the animation short­hand prop­erty to run our anim­a­tion over 10 seconds with steps 1 second apart. We also want the anim­a­tion looped infin­itely:

.timer {
animation: timer 10s steps(10, start) infinite;
}

Now it gets a little more com­plex. We need to use the mask to fill the left side of the pie timer ele­ment with the sec­ond­ary col­our dur­ing the first five seconds of the anim­a­tion and then to fill the right side with the primary col­our dur­ing the last five seconds. As our mask is a psuedo-ele­ment, we also need to neg­ate the spin­ning on the pie timer ele­ment to keep our mask on the cor­rect side for each half of the anim­a­tion. Here are our key­frames: