I am working on a countdown in css to display time left for certain metrics. Everything is working well, with the exception that I can only display the remaining time in seconds, instead of minutes.
From my understanding of countdown animations, they only accept time in seconds or milliseconds. My timer is for 25 minutes so I have it set for 1500 seconds and it works great. I cannot find a way to divide the results of my counter s by 60 to get the time to display in minutes using countdown content. I have also tired just basic calc(1 + 1) and trying to get that result to display in content, but have be unsuccessful. It would seem that any calculated result will down display in content. It felt like a variable type issue, but don’t believe CSS uses typed variables.
I have been trying to avoid adding JavaScript into this project, but would that be the recommendation to move forward or is there something I am missing with the CSS?
@property --t {
syntax: "<number>";
initial-value: 1500;
inherits: true;
}
/* won't be needed once Chrome supports round() */
@property --s {
syntax: "<integer>";
initial-value: 0;
inherits: true;
}
.countdown {
--s: calc(var(--t)/1);
display: grid;
margin: 1em auto;
width: 20em;
height: 20em;
animation: t 1500s linear forwards ;
}
.countdown::after {
grid-column: 1;
grid-row: 1;
place-self: center;
font: 5em/2 ubuntu mono, consolas, monaco, monospace;
counter-reset: s var(--s);
--k: counter(s);
content: var(--k);
}
<body>
<div style="font: 5em/2 ubuntu mono, consolas, monaco, monospace;color:black;text-align: center;">Processing</div>
<!-- partial:index.partial.html -->
<div class="countdown">
<svg viewBox="-50 -50 100 100" stroke-width="10">
<circle r="45"></circle>
<circle r="45" pathLength="1"></circle>
</svg>
</div>
<!-- partial -->
</body>
I started with this code and adapted to my needs. In this example the leading 0: appears to just be a string prefix for aesthetics.
2
Answers
It’s overall simple.
Doing the calculation
You need to calculate the minutes based on the seconds you got. The simple formula is
--m: round(var(--s) / 60);
wherem
is minutes ands
is seconds. Because round is not globally available (yet), you have to use some tricks to emulate it. So the final formula would be something like this:--m: max(0, var(--t)/60 - 0.5);
(the full explanation for the formula is here, gut in short the- 0.5
is used to round down, the max is used to prevent negatives when the number is below 1 and--m
is defined as integer to round the value)If you want also to show the seconds the process is similar. The formula would be s = t – m * 60 which translated to css with the limitations we have would be
--s: calc(var(--t) - var(--m)*60 - 0.5);
Displaying both values
finally you just have to define both minutes and seconds on your counter to display them like so:
counter-reset: s var(--s) m var(--m);
and then, instead of the ’00:’ which was burned in, we display the minutes like so:
content: counter(m) ':' counter(s, decimal-leading-zero);
if you only want to show the minutes, you can delete the seconds part like so:
content: counter(m);
(and remove the calculation as well)Fully working example
and that’s it, this is a fully working example, based on the pen you provided (this is how it would look like with about 90 seconds set up)
https://codepen.io/danicruz0415/pen/pomvzXe
Full code reference
here is the full code in case the pen stops working. I dont put it like a runnable snipped because its done in scss and pug but you can adapt it later to your code, because the code you provided was not fully working
I thought you might enjoy seeing how this could be accomplished with js instead of pure css solution.