1st, 2nd, 3rd, nth … Generating Dynamic Ordinal Numbers with just CSS

Mate Marschalko
6 min readSep 6, 2022

To understand CSS Counters and what we can use them for, what the possibilities and also limitations are, let’s look at an interesting challenge: try and count DOM elements on the page and label them with dynamically generated ordinal numbers!

To start counting we need a few elements on the page. Let’s start with 100 list items in an unordered list:

<main>
<h1 id="main-title">The power of counters</h1>
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<!-- 100 items in total -->
</ul>
<main>

To count all the list items, we need to initialise a CSS counter with an initial value and we can do exactly that with the counter-reset property:

main {
padding: 50px;
counter-reset: list-counter 0;
}

The counter-reset property can be added to any of the ancestor elements where we want the counter to reset to 0. In this instance, we added it to main, but we could have added it to body, html or the :root.

Next, we need to add the counter-increment property to the selector where we want the list-counter to be incremented. To count every single list item, we add it to the li element selector:

li {
margin-bottom: 20px;
margin-left: 50px;
counter-increment: list-counter 1;
}

We now have most of the elements in place for the counter to work. The browser will reset the counter to 0 when it reaches the main element, then it will increment the value by one every time it encounters a list item so it will get to 100 by the time it reaches the end.

We have just one problem…

We are unable to see the result and that makes this counter pretty useless. But instead of just displaying the total number of list items (100), let’s use the counter to add numbering next to every list item.

You probably know that we can use the content property inside the ::after and ::before pseudo-elements to inject some text content into the document. I also used the attr() function to pull in values from HTML attributes and display them in these two examples:

--

--

Mate Marschalko

Senior Creative Developer, Generative AI, Electronics with over 15 years experience | JavaScript, HTML, CSS