Hajime, the duck guy

UX and graphics kata
On this page
Level: Essential

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 --value and --max CSS 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

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.

Want more?

Back to top