CSS Pie Timer Re-Re-Revisited !

new solution with one div and only one pseudo-element

cross-browser without prefixes or flags

even IE-11 proof  

Intro: the Pie Timer article updated and continued

This exercise was triggered by the different variants described or linked in the page css-tricks.com/css-pie-timer-re-revisited.

My challenge was to find a cross browser solution, to get rid of one pseudo element, and to get the smallest amount of CSS lines for that. I guess I've baked a tasty pie of 25 css-lines (uncompressed).
Step 1 to Step 5 is the buiding process, Step 6 is the result.

Step 1

<div>
<lin.grad.>
bg-colpie-col
<combi>

Kitty's revised version has an animated :before pseudo-element as mask for the right side. In order to save this pseudo-element, we can replace the desired solid background color by a linear gradient background-image (of the div itself) with the background color left, the desired pie color right, and a sharp color stop halfway.

<div class="pie"></div>
.pie {
  width: 70px;
  height: 70px;
  border: 2px solid DeepPink;
  border-radius: 50%;
  background-image: linear-gradient(90deg, Aquamarine 50%, DeepPink 50%);
  position: relative;
}

Because the background-image is a background, it will end at the border of the circle: there is no need to set a hidden overflow at the moment.

Step 2

<div>
<:after>
transpbg-col
<combi>

The hands are free to style an :after pseudo-element: as right part column of the div area, with the background-color of the div. The left side of the area can stay transparent to show the background-color of the div layer.

.pie {
  ...
  overflow: hidden;
}
.pie:after {
  position: absolute;
  left: 50%;
  width: 50%;
  height: 100%;
  content: "";
  background: Aquamarine;
}

Because the :after is absolute positioned for independent manipulations, this time the div needs the {overflow: hidden;}.
This way the pseudo-element is exactly covering the right half of the circle. It seems just the same as our starting image, but that's not true! The difference is:

Step 3

<div>
<:after>
<combi>

Now the animation can take place: rotating the pseudo-element and revealing the pie. In order to see what happens: just one turn of 360deg.

.pie:after {
  ...
  transform-origin: 0 50%;
  animation: pieAniAfter 5s linear forwards;
}
@keyframes pieAniAfter {
  0% {transform: rotate(0deg)}
  100% {transform: rotate(360deg)}
}

Oops alert ! Halfway the rotation: the front of the :after-color is eating the pie at 12 o'clock and later! Soon there is no pie left...
So the animation has to stop at 180deg. That is this one:

Step 4

<div>
<:after>
<combi>

That's o.k. now.

.pie:after {
  ...
  animation: pieAniAfterHalf 2.5s linear forwards;
}
@keyframes pieAniAfterHalf {
  0% {transform: rotate(0deg)}
  100% {transform: rotate(180deg)}
}

And the filling of the other half?

Step 5

<div>
<:after>
<combi>

The magic switch ! - For the second half the we can recycle the useless :after-rules.
In this case the opposite of what we have done: not revealing the right side, but filling the left side with the pie color.
Or: instead of "rotating the negative" we can "rotate the positive". To get the positive turn is easy: just change the background-color of the :after into the pie color, and let the rotation start again at the top.
Note: the left side of the :after area can stay transparent again: first to show the (disappearing) background-color of the div layer, and after 12 o'clock to keep the pie color of the div on the right side alive: no harm.

.pie:after {
  ...
  background: DeepPink; animation: pieAniAfterHalf 2.5s linear forwards;
}

Step 6: the result

The only thing resting is to glue together the results of Step 4 and Step 5, in one combined animation with a sharp switch at 180deg. Also the temporary forwards of the animation can change into infinite for endless spinning.

The definitive pie timer and code is:

<div class="pie"></div>
.pie {
  width: 70px;
  height: 70px;
  border: 2px solid DeepPink;
  border-radius: 50%;
  background-image: linear-gradient(90deg, Aquamarine 50%, DeepPink 50%);
  position: relative;
  overflow: hidden;
}

.pie:after {
  position: absolute;
  left: 50%;
  width: 50%;
  height: 100%;
  content: "";
  background: Aquamarine;
  transform-origin: 0 50%;
  animation: pieAniAfter 5s linear infinite;
}

@keyframes pieAniAfter {
  0%     { transform: rotate(0deg);   background: Aquamarine; }
  49.99% { transform: rotate(180deg); background: Aquamarine; }
  50%    { transform: rotate(0deg);   background: DeepPink; }
  99.99% { transform: rotate(180deg); background: DeepPink; }
  100%   { transform: rotate(0deg);   background: Aquamarine; }
}

Evaluation

Tested and supported in: Firefox, Chrome, Opera, Vivaldi, IE-11, MS-Edge; all on desktop.
Not tested: tablets and the arsenal of mobile devices, but I assume they don't perform worse than IE-11.

The clean result without the steps is on this page:

Francky Kleyneman
May 25, 2021

proudly made with