Progress clocks re helpful for monitoring progress towards a activity or aim. They’re easy and intuitive when used with pen and paper; this text will carry them to the online with HTML and CSS.
Within the tutorial portion of this text, we’ll construct an eight-segment progress clock. We’ll make updates to our venture course of tracker design for usability and inclusivity.
Soar forward:
Overview
Semantically, a progress clock isn’t any totally different from a gauge or a progress monitoring bar. It’s a illustration of how a lot progress you’ve made towards a selected aim. Nonetheless, progress bars are often a visible component up to date by code, whereas a progress clock is mostly an interactive management up to date by the person.
Visually, a progress clock is a circle divided into segments, which get crammed in as progress is made. The board sport Trivial Pursuit makes use of a progress clock mannequin for the enjoying items; gamers bodily fill in segments as they progress by means of the sport.
You’ll have additionally seen the progress clock mannequin utilized in video video games. For instance, in Tremendous Mario 64, Mario’s “Well being Meter” is famously expressed as a progress clock, with segments filling in because the character positive aspects “well being”.
A number of tabletop role-playing video games additionally use progress clocks as a easy mechanic to both monitor progress or handle dramatic rigidity.
Progress clocks are excellent for visually speaking progress “at a look” so long as the variety of segments is small. I typically discover that greater than 12 segments may be complicated. In actual fact, 12 segments might be solely acceptable for those who’re leaning into the “clock” a part of the metaphor.
Design objectives
A typical train for designers or builders is breaking down initiatives into duties and monitor progress towards them, so there’s no scarcity of available instruments for this effort. In actual fact, constructing a to-do record utility is usually one of many first initiatives that many net builders construct.
The important thing performance {that a} progress clock offers is the flexibility for the person to interactively set the quantity of progress. This tells us a couple of issues concerning the forms of eventualities the place a progress clock is most helpful.
Extra nice articles from LogRocket:
Easy duties like “feeding the cat” usually don’t want a progress replace. They’re both performed or not performed. Any such activity is an effective candidate for a standard checkbox.
Complicated duties that may be damaged down into easy duties don’t should be interactively up to date by the person. With the sort of activity, you’ll be able to measure progress by calculating the proportion of accomplished subtasks. Most subject trackers have this performance in-built!
Complicated duties the place progress may be objectively measured don’t should be interactively up to date by the person both. For instance, my train tracker mechanically calculates how a lot progress I’ve made towards my health objectives. Equally, my budgeting software program can calculate my progress towards my financial savings objectives.
What does this inform us? It means that progress clocks are finest suited to conditions the place we have to monitor our progress, however can’t mechanically calculate the quantity that’s accomplished or can’t simply break down the venture right into a set of less complicated duties.
We don’t require nice precision for our progress clocks. Since every clock has a comparatively small variety of segments, we’re solely getting a tough approximation of our progress. This suggests that progress clocks are finest used for duties the place progress is considerably summary or subjective.
For initiatives requiring numerous segments, a spread management (<enter sort="vary" />
) could also be extra applicable. That is nonetheless an imprecise methodology, however it will possibly accommodate a a lot bigger vary of values than a progress clock with out changing into tough to make use of.
For initiatives requiring extra precision, we are able to use a numeric management (<enter sort="quantity" />
) with the suitable minimal, most, and step values.
For initiatives with an mechanically calculated or read-only presentation, the usual <progress>
or <meter>
components could also be extra applicable
In my very own expertise, progress clocks are most fitted for inventive duties, like “writing an article” or these which can be tough to measure, like “performing a root trigger evaluation”.
For most of these duties, we’d need to depend on human experience and judgment to get a way of progress.
Progress clocks are additionally helpful for duties with a small variety of steps that advance in unpredictable or sporadic methods. That makes them very helpful for video games, the place randomness might play a component in shifting the participant towards (or away from) their aim.
Implementation
Every progress clock section must be individually focusable and selectable. Since we’re choosing solely one among a small variety of segments, radio buttons are a sensible choice for the underlying markup.
By utilizing radio buttons, our part will already be geared up with all of the habits we want. It additionally implies that our management stays useful (if ugly). In different phrases, you’ll be able to nonetheless replace your progress in conditions the place the CSS fails to load.
For this text, I’ve chosen to construct an eight-segment progress clock. This measurement is an effective default; as a good quantity it permits us to simply present “half accomplished”. Additionally, you’ll be able to advance by two segments at a time to substitute for a four-segment clock.
I’ll additionally present the overall method to allow you to construct progress clocks with any variety of segments.
Right here’s our beginning markup:
<fieldset class="clock-frame"> <legend>Pattern Progress Clock</legend> <div class="clock" data-segments="8"> <enter sort="radio" title="progress-clock" worth="8" id="segment-8" /><label for="segment-8">8/8</label> <enter sort="radio" title="progress-clock" worth="7" id="segment-7" /><label for="segment-7">7/8</label> <enter sort="radio" title="progress-clock" worth="6" id="segment-6" /><label for="segment-6">6/8</label> <enter sort="radio" title="progress-clock" worth="5" id="segment-5" /><label for="segment-5">5/8</label> <enter sort="radio" title="progress-clock" worth="4" id="segment-4" /><label for="segment-4">4/8</label> <enter sort="radio" title="progress-clock" worth="3" id="segment-3" /><label for="segment-3">3/8</label> <enter sort="radio" title="progress-clock" worth="2" id="segment-2" /><label for="segment-2">2/8</label> <enter sort="radio" title="progress-clock" worth="1" id="segment-1" /><label for="segment-1">1/8</label> </div> </fieldset>
Right here, we use a fieldset
to group the radio button controls collectively. The legend
will act as a label
for the group, which is useful as we intend for the group to appear like a single management.
Some display screen readers will learn the legend out when getting into the fieldset
, together with the label
of the primary enter. For instance, NVDA will announce “Pattern Progress Clock, 8/8”. Different display screen readers will learn the legend out for each management within the fieldset
.
Our preliminary CSS is a straightforward reset that eliminates the usual radio button look, hides the labels, and provides the clock itself a short lived background whereas we work on the general management.
.clock { background-color: darkcyan; } .clock label { show: none; } .clock enter { look: none; }
We’ll start creating the true format by drawing the inputs ourselves. We begin by making the packing containers the identical measurement. The cursor: pointer
rule makes it extra apparent to a person that the packing containers are clickable. We point out the checked enter with a special background colour.
.clock enter { look: none; show:inline-block; box-sizing: border-box; font-size:inherit; margin: 0; width: 2em; top: 2em; background-color: #eee; border: 1px stable #ccc; cursor: pointer; } .clock enter:checked { background-color: #222; }
Now, we’re going to place the packing containers as pie slices; that is the place the variety of segments turns into vital.
To perform this, we’re going to place all of the enter packing containers so they’re in the identical spot, then use the CSS remodel
property to rotate the packing containers individually into place.
As a result of absolute positioning will take the packing containers out of movement, we have to give the containing div an specific width and top. If we fail to do that, the packing containers would shrink to zero and we’d see nothing. You’ll be able to see why having the short-term background colour is useful at this level, because it permits us to note this sort of error.
Sooner or later, once we can use attr()
to learn the worth attribute, we’ll be capable to use calc()
to mechanically decide the rotate and skew values.
.clock { --segment-size: calc(360deg / attr(data-segments integer)); } .clock enter { remodel: rotate(calc(var(--segment-size) * (attr(worth integer) - 1))) skewY(calc(var(--segment-size) - 90deg)); }
At current, we’ll need to calculate the remodel
ourselves. However, the method is fairly easy.
The section measurement is obtained by dividing 360deg (a full circle) by the variety of segments. For an eight-segment clock, every section could be 45deg. For a six-segment clock, every section could be 60deg.
The skew is identical for all segments — it’s our section measurement much less 90deg. For our eight-segment clock, that’s -45deg
. For a six-segment clock, that might be -30deg
.
The rotation for every section is:
section measurement * (section quantity – 1)
So the rotation of the fourth section of an eight-segment clock could also be calculated as follows:
45deg * (4 - 1) = 135deg
Nonetheless, I’ve our values operating in reverse order, from highest to lowest, for causes that may quickly turn into clear. So, we’re going to subtract 360deg, which is able to give us a rotation of -225deg
.
.clock { place: relative; background-color:darkcyan; width:4em; top:4em; } .clock enter { look: none; show:inline-block; box-sizing: border-box; font-size:inherit; margin: 0; width: 2em; top: 2em; background-color: #eee; border: 1px stable #ccc; cursor: pointer; place: absolute; left:2em; backside:2em; high:auto; transform-origin:0 2em; } .clock enter[value="8"] { remodel: rotate(-45deg) skewY(-45deg); } .clock enter[value="7"] { remodel: rotate(-90deg) skewY(-45deg); } .clock enter[value="6"] { remodel: rotate(-135deg) skewY(-45deg); } .clock enter[value="5"] { remodel: rotate(-180deg) skewY(-45deg); } .clock enter[value="4"] { remodel: rotate(-225deg) skewY(-45deg); } .clock enter[value="3"] { remodel: rotate(-270deg) skewY(-45deg); } .clock enter[value="2"] { remodel: rotate(-315deg) skewY(-45deg); } .clock enter[value="1"] {remodel: rotate(0deg) skewY(-45deg); }
At this level, we’ve got one thing resembling a rosette star overflowing our container. The toughest step is behind us now, we simply want to wash up and repair up a couple of accessibility points.
Turning the star right into a circle is straightforward, we simply give the container a border radius of fifty % and conceal any overflow. Lastly, we add a border to the circle.
.clock { place:relative; width:4em; top:4em; overflow:hidden; border:medium stable #666; border-radius:50%; }
Now, we’ve got one final rule that offers us that visible sense of progress, the entire level of this train.
Due to our preliminary selection of ordering the values from highest to lowest, we are able to use the beneath sibling selector to supply the visible phantasm of all lesser values being chosen.
.clock enter:checked, .clock enter:checked ~ enter { background-color: #222; }
Design assessment
Whereas our progress clock has all of the distinctive options and habits we meant, it has some shortcomings that we’ll want to handle earlier than utilizing it on an precise web site. As well as, we should always undergo a usability guidelines to make sure our design is inclusive.
Including a zero worth
Our first actual usability subject is the shortage of a zero worth. And not using a zero worth, we are able to’t mirror “no progress has been made”, we are able to’t simply repair a mistake through which we unintentionally mark progress on the unsuitable activity, and we don’t have a default worth for a newly created progress clock.
There’s no apparent place to place the zero worth within the clock itself, however we are able to reap the benefits of our radio button semantics!
We will put the zero worth exterior the clock, however have it handled as a part of the identical set of inputs as the traditional segments.
<fieldset class="clock-frame"> <legend>Pattern Progress Clock</legend> <p class="zero-progress"><label><enter sort="radio" title="progress-clock" worth="0" checked="checked" class="visually-hidden" />Clear</label></p> <div class="clock" data-segments="8"> <enter sort="radio" title="progress-clock" worth="8" id="segment-8" /><label for="segment-8">8/8</label> <enter sort="radio" title="progress-clock" worth="7" id="segment-7" /><label for="segment-7">7/8</label> <enter sort="radio" title="progress-clock" worth="6" id="segment-6" /><label for="segment-6">6/8</label> <enter sort="radio" title="progress-clock" worth="5" id="segment-5" /><label for="segment-5">5/8</label> <enter sort="radio" title="progress-clock" worth="4" id="segment-4" /><label for="segment-4">4/8</label> <enter sort="radio" title="progress-clock" worth="3" id="segment-3" /><label for="segment-3">3/8</label> <enter sort="radio" title="progress-clock" worth="2" id="segment-2" /><label for="segment-2">2/8</label> <enter sort="radio" title="progress-clock" worth="1" id="segment-1" /><label for="segment-1">1/8</label> </div> </fieldset>
We will fashion this to appear like a button that clears the progress clock, and every little thing works as you would possibly anticipate. Effectively, nearly every little thing as you’ll discover within the subsequent part.
Implementing a spotlight indicator
One piece of performance that we haven’t restored is a spotlight indicator. That is particularly vital for keyboard customers, as they will tab into our radio button group however get no visible suggestions about their navigation.
We will make the clock itself seem like a single management by utilizing the :focus-within
pseudo-class. We’ll change the border colour and add a top level view, which is similar to the default radio button habits in my browser. Nonetheless, we additionally want to point which enter really has the main focus. Right here we try this by altering the section colour.
These modifications make it potential for a keyboard person to work together with our progress clock simply as in the event that they had been utilizing a set of radio buttons, together with utilizing the arrow keys to vary the chosen section in a well-known and intuitive approach.
Besides, as you will note for those who experiment, for one surprising little bit of habits.
The zero worth seems to be a separate button management, however it’s really a part of the radio group. So when tabbing, both the progress clock or the button positive aspects focus, and the opposite seems to be not selectable. Nonetheless, utilizing the arrow keys instantly reveals the connection between the button and the clock.
I don’t have an excellent answer for this. Changing the zero worth radio button with an precise button might result in extra intuitive habits at the price of semantics. Usability testing might be warranted to determine which strategy is finest.
.clock:focus-within { border: medium stable blue; define: medium stable rgb(112, 179, 255); outline-offset: 2px; } .clock enter:focus { background-color: rgb(0, 119, 255); }
Enhancing the fieldset
presentation
The fieldset
is clearly the right semantic selection for grouping our radio buttons collectively, however we are able to positively enhance upon the default presentation.
Controlling the positioning of the legend
was once a bit tough. Fortunately, we are able to reap the benefits of a flex context to place the legend
wherever we like.
We float
the legend
to detach it from the fieldset
border, then flip the fieldset
right into a flex container. As a result of float
doesn’t take flex objects out of movement, we are able to now deal with the legend
as a normal flex merchandise and management its positioning that approach. On this case, we use the order
property to position it beneath the clock itself in order that it seems to be a label for the clock.
.clock-frame { show: inline-flex; flex-direction: column; border-radius: 2%; place: relative; justify-content: middle; width: fit-content; padding: 1em; hole: 1em; } .clock-frame legend { float:left; order: 3; }
Supporting wonderful and coarse pointers
The phrases “wonderful” and “coarse” come from the pointer media question, the place we distinguish between wonderful, excessive precision enter strategies (like a mouse or stylus) and coarse, low accuracy enter strategies (like a online game controller or good TV distant).
It may be exhausting to make sure collection of the right section with a rough pointer. Nonetheless, there are three approaches that may make this simpler, Your selection of strategy will rely upon what works finest in your design.
Enlarging the clock
The primary strategy we are able to take to make choice with a rough pointer simpler is to make the clock bigger. As a result of every little thing is expressed in ems, we are able to merely bump up the font-size of the clock, and every little thing will scale accordingly. This strategy additionally can be utilized to create a bigger energetic space for contact interfaces.
.clock { font-size: xx-large; }
Including a hover fashion
A second strategy is so as to add a hover fashion that may present visible suggestions for supported person enter mechanisms (for instance, a mouse or stylus). This offers a person with confidence relating to their section selection as they make their choice.
On this instance, I’ve used two colours on hover – one for unselected values, and a second for chosen values. I consider this makes it clearer whether or not we can be growing or reducing the worth, however it’s best to conduct person testing to find out if that is true!
.clock enter:hover { background-color: violet; } .clock enter:hover ~ enter { background-color: violet; } .clock enter:checked:hover, .clock enter:checked:hover ~enter, .clock enter:checked ~ enter:hover, .clock enter:checked ~ enter:hover ~ enter, .clock enter:hover ~ enter:checked, .clock enter:hover ~ enter:checked ~ enter { background-color: rebeccapurple; }
Utilizing a horizontal or vertical format
A 3rd strategy to make choice with a rough pointer simpler is to vary from a round progress clock to a horizontal (or vertical) progress tracker.
Frequent examples of the sort of tracker are star scores (e.g., three out of 5 stars), fundraising thermometers, and gaming well being bars (such because the one in Legend of Zelda). The important thing benefit to this format is that the person values are simpler to pick out with a low-accuracy pointer.
For this instance, I’m simply going so as to add an additional class in order that we are able to simply toggle the monitor look on and off with JavaScript. In an precise design, I’d wrap these types inside a media question to manage when a clock will get offered as a monitor.
.clock.monitor { background-color:clear; width: auto; top:auto; overflow: auto; border:none; margin: 0 0 0 auto; border-radius: 0; show: flex; flex-direction: row-reverse; hole: 0.25em; } .clock.monitor enter { remodel: none; place: static; }
Wrapping up
On this article, we’ve explored find out how to construct a progress clock with CSS. Now, we are able to put every little thing we’ve mentioned right into a remaining working pattern.
See the Pen
Progress Clock by John C Barstow (@jbowtie)
on CodePen.
I’ve added some buttons that may allow you experiment with the font measurement and change between the progress clock and progress bar varieties.
Is your frontend hogging your customers’ CPU?
As net frontends get more and more complicated, resource-greedy options demand an increasing number of from the browser. In the event you’re all in favour of monitoring and monitoring client-side CPU utilization, reminiscence utilization, and extra for all your customers in manufacturing, attempt LogRocket.https://logrocket.com/signup/
LogRocket is sort of a DVR for net and cellular apps, recording every little thing that occurs in your net app or website. As an alternative of guessing why issues occur, you’ll be able to mixture and report on key frontend efficiency metrics, replay person classes together with utility state, log community requests, and mechanically floor all errors.
Modernize the way you debug net and cellular apps — Begin monitoring free of charge.