Simple progress bar
Build a progress bar using CSS custom properties
The way of kata
Kata is an exercise for muscle memory. It's not intended to fill your brain with information but train your fingers to react. The information is there to give you the why, but your fingers need to learn the how.
The material on this page is presented in a specific order — from least specific to highly technical. You will learn the most by jumping in as soon as you have some idea of what you should do. Once you're done, read the rest of the material and check your solution.
All katas are designed to be doable without using 3rd party libraries (and, in fact, the point is to also learn how to do what these libraries do).
To make the best of katas, observe the following rules.
- Don't rush.
- When stuck, take a break and do something unrelated.
- Do not copy/paste code. Always retype everything.
- Do not use AI tools to generate code.
- Try to do something that wasn't in the instructions, experiment.
- Repeat the kata from time to time, even if you think you've got it.
- You have mastered the kata once you are able to complete it without thinking too much.
Remember, the goal is not to get it done, but to get some practice.
Introduction
In this exercise, you will practice using CSS custom properties to control the value of a progress bar.
Skills you will acquire
- Using custom CSS properties (variables) to parametrize appearance
- Controlling CSS properties using JavaScript
Objective
- Create two progress bars
- One progress bar shows a constant value
- Another progress bar counts the seconds up to a minute, and then goes backwards
Check your solution
- The page shows two progress bars
- The percentage of the progress bar is controlled using
--valueand--maxCSS properties - The first progress bar has a maximum of 200, and is at 30%
- The second progress bar goes from 0 to 60 in one minute, progressing 1 unit per second, and then goes back to 0, and repeats this motion in a loop
- The change in progress is animated
Keep in mind
In most applications, there are two kind of values. The "business domain" values
(e.g., "time until arrival", "quantity of products", "distance travelled"). The
domain refers to "what the app is about". There are also values related to
technology that are not directly relevant to the business. For example, width of
the element, remaining storage, time it takes to send a request. In the case of
user interfaces, we are talking about values such as percentages, pixels, em,
animation duration in milliseconds, timestamps etc.
In this exercise, the --value and --max refer to business domain values. And
you are to convert them into UI-specific values (e.g., percentage) before
applying them to the styling.
Complete the static progress bar first. This will serve as a basis for JavaScript-enabled version.
The progress bar consists of two elements. The bar which represents the total value, and the progress indicator that indicates the current progress towards the total. You will need exactly one HTML element to implement this widget.
To achieve the appearance of the progress bar, there are several methods that
you could use. One is to use a pseudo-element (e.g., ::before) and control its
position and width within the parent element. The second option is to use a
linear gradient.
Unlike normal CSS properties, custom properties cannot be set directly on the
Element.style property. Instead, we use the setPropety() method.
Reading list
- Using CSS custom properties (variables) (MDN)
::before(MDN)background-image(MDN)linear-gradient()(MDN)CSSStyleDeclaration.setProperty()(MDN)
Hints and spoilers
Hint: applying the custom CSS properties in HTML
The custom CSS properties can be applied to elements using the style
attribute. (I consider this the only valid use case for this attribute, btw.)
For example:
<div style="--max: 200"></div>
You can apply any number of custom properties this way, separating them with
semi-colon ; just like in CSS.