Using CSS Counters for Styling Numbered Content 
Tags: css, webdev
Published: 2020-04-22 00:10:21

One of my favorite up and coming updates to CSS is the `::marker` pseudo element. There have been so many situations where I am styling a website and I need the list item indicator to just be a different color. Until recently, the best way to do this would be to remove the list style, and re-add it using a `:before` element on the list item, which is a lot of CSS for just one little thing.

Now, instead of writing all of this CSS:

{% codepen https://codepen.io/LegendOfLuis/pen/YzyGzWj default-tab=css,result %}

I can do it with literally one line:

{% codepen https://codepen.io/LegendOfLuis/pen/JjYRjRO default-tab=css,result %}

Unfortunately, `::marker` is only [supported on Firefox by default](https://developer.mozilla.org/en-US/docs/Web/CSS/%3A%3Amarker) and through flags on Edge and Chrome, so it's not widely available yet. So until then, I'll have to stick with the old way.

The former approach works great for unordered lists, but I was recently given a task where I had to change the color of the indicators in a ordered list, which are incrementing digits. This is where CSS counters come in! CSS counters allows CSS to automatically count elements and create incrementing numbers. This not only works on lists, it can count and display a number for any element. It's pretty neat!

In order to use this, there are a few properties and functions to know about:

- `counter-reset` - Creates or resets a counter
- `counter-increment` - Increments a counter value
- `counter()` or `counters()` - Adds the value of a counter to an element

To begin using CSS Counters, you will need to use `counter-reset` on an element to define counter that you want to use:

```css
ul {
  counter-reset: my-awesome-counter;
}
```

`counter-reset` works by passing in a name for the counter as its value. It can be called anything you want, with the same naming restrictions as classes or IDs. This will also reset the value of the counter to 0 if it has been used before. You can then reference it with the `counter-increment` property:

```css
li {
  counter-increment: my-awesome-counter;
}
```

This will increase the counter called `my-awesome-counter` by 1 for every `li` inside the parent `ul` where we defined the counter. That on it's own won't really do anything though. If you actually want to see the number being incremented, The `counter()` function will output the value of a given counter:

```css
li:before {
  content: counter(my-awesome-counter);
}
```
Putting it all together, you can now create a custom counter for your ordered lists:

{% codepen https://codepen.io/LegendOfLuis/pen/Yzypayr default-tab=css,result %}

There is also a `counters()` function which will allow nested counters with the same name to be combined into subcounters. That function takes a second argument that defines a string to be used as a separator:

{% codepen https://codepen.io/LegendOfLuis/pen/wvKomGQ default-tab=css,result %}

Finally, as I mentioned before this can be used on all sorts of elements, and combined to create hierarchical content structures:

{% codepen https://codepen.io/LegendOfLuis/pen/VwvmXmr default-tab=css,result %}

CSS counters are an awesome and flexible tool to have around, there are so many creative way to use it. Have you implemented CSS counters in previous projects to solve a problem?

To learn more, check out the [CSS Counters Guide](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Lists_and_Counters/Using_CSS_counters) on the MDN Web Docs.