Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
July 19, 2021 09:15 am GMT

Tell your users the remaining reading time, in CSS

Note: this demo must be tested in Chrome Canary 90+ with the --enable-experimental-web-platform-features flag enabled;

Recently, thanks to the new @scroll-timeline property available on Chrome Canary, I have seen an interesting demo by @bramus where the user is aware of the time needed to read a page with a sticky progress bar that stretches horizontally, where its width is dependant on the current scrolling position of the root element.

I've extended this idea a little bit by showing an animated countdown of the exact time needed to read the page. All you need to do is to just set the time in minutes and the CSS animations will do the work for you.

Demo (scroll the page until the end):

How does it work?

Here is a step-by-step explanation

The variables

Basically, two variables --ss and --mm hold the values of seconds and minutes and two distinct animations change them. In order to make the interpolation of the values in the keyframes work, these variables have been registered as integers properties through the Houdini's API integrated on Chrome.

So the --ss variable is declared in the CSS like this:

@property --ss {  syntax: "<integer>";  initial-value: 0;  inherits: true;}

while the --mm is declared instead in a <style> block, inside the markup because here is where you are going to set the minutes needed (e.g. 7):

<style>    @property --mm {       syntax: "<integer>";       initial-value: 7;       inherits: true;    }</style>

Since it's not (still) possibile to print out the value of a variable using the content property I've set two counters and print their values through the counter() function with a leading 0 when necessary

counter-reset: ss var(--ss);...content: counter(ss, decimal-leading-zero);

and

counter-reset: mm var(--mm);...content: counter(mm, decimal-leading-zero);

The scroll-timeline

I've set the scroll-timeline animation in this way

@scroll-timeline scroll {  time-range: 60s;  start: 200px;  end  : calc(100% - 150px);}

The time-range has been set to 60 seconds in order to make the calculations of the animations easier (at least for my brain) .

To give a meaningful example let's say that we want to start the countdown after 200px of scroll to exclude the title or maybe a hero image, but you could even set it to 0 or to another value of course and we want to also stop it before a hypothetical footer 150px tall.

The animations

This is the most intriguing part due to the tricky computations. Here is the animation of the minutes

@keyframes mins {  to   { --mm: 0;  }}...animation: mins    /* duration   */ 60s    /* timing     */ steps(var(--mm), start)    /* delay      */ calc(calc(60s / (calc(var(--mm)) - 1)) / 60 / var(--mm))   /* repetition */ 1   /* fill mode  */ forwards;

The @keyframes start from the value we have previously set and should decrease until 0, so the definition of the last keyframe is enough.

The animation should takes 60s which is the same amount of time we defined for the @scroll-timeline. The delay expression is calculated so that the value of the minutes decreases immediately after 1s (e.g. switching from 7:00 to 6:59).

The animation of seconds is quite similar but in this case we need to specify the starting value

@keyframes secs {  from { --ss: 59; }  to   { --ss: 0;  }}...animation: secs    /* duration   */ calc(60s / calc(var(--mm)))   /* timing     */ linear   /* delay      */ calc(calc(60s / (calc(var(--mm)) - 1)) / 60 / var(--mm))   /* repetition */ var(--mm)    /* fill-mode  */ forwards;

The only difference here is the duration: seconds need to be updated faster than minutes, running --mm times from 59 to 0 with a repetition of --mm. Here the purpose of the delay is just to wait the first update of the minutes.

Always respect user preferences

The update of the seconds is amazing but it can be annoying for users who don't like continuous animations and that prefer a reduced motion.

We may use a simple mediaquery:

@media (prefers-reduced-motion: reduce) {  .countdown__display--ss {    display: none;  }}

and hide the element with the seconds.

Ta-da!

Wall-E

Final words & thoughts

Feel free to follow me on Codepen or Twitter where I usually talk about frontend and trees.

Note: This is a carbon free article so I pledge to plant 25 trees with Ecologi plus 1 tree for each retweet of the announcement below in the next 12 days

(up to 75 trees, retweets from human accounts with 20+ followers)


Original Link: https://dev.to/fcalderan/tell-your-users-the-remaining-reading-time-in-css-1mik

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To