CSS provides a counting functionality in its generated content through the use of counters. Counters keep track of the number of elements within a context and display numbers before or after the actual content of an element thanks to the :before
and :after
pseudo-elements. First of all, each counter must be initialized with the counter-reset
property on the parent node of elements that we want to have counters. This property accepts a user-defined identifier, for example item
. This will be the name of the counter that will be used within our element context. Then, a counter must be incremented through the counter-increment
property that accepts the same user-defined identifier that we have specified earlier (in our case, item
). This property must be specified on the elements that will actually display their counters. Finally, the actual numbering system will be displayed by the content
property used within a :before
or :after
pseudo-element.
For example, if we want to display a simple numbering system on a single unordered list, we could write:
ul { list-style: none; counter-reset: item; } li { counter-increment: item; } li:before { content: counter(item)'. '; }
The counter()
function actually turns all our counters into values that can be passed to the content
property. The drawback of this approach is that we should write multiple counters if we have to deal with nested elements (in this case, nested lists). For that reason, CSS allows the counters()
function to generate all these counters automatically. This function has the following syntax:
counters(identifier, separator)
where identifier
is the usual counter identifier we mentioned earlier and separator
is a string that will be used together with the counter itself (for example, a period in 1.2 or 1.2.1). Let's see something practical. We have three nested unordered lists and we want to attach nested counters to them. Here's how we can do:
ul { list-style: none; counter-reset: item; } li { counter-increment: item; } li:before { content: counters(item, '. ') ' '; }
You can see the result in the demo below.