Web browsers let you customize the look of most aspects of a page using CSS. But when rendering some page elements, web browsers are resistant to your styling efforts. For example, form elements like select menus, radio buttons and checkboxes have a certain look for each operating system, and browsers try to enforce that look in web forms.

Web browsers also dictate the way that bulleted and numbered lists should look. For example, browsers make it hard to change the style of bullets in unordered lists or numbers in ordered lists. Sure, there are a few CSS styles like list-style-type, list-style-image, and list-style-position, but doing something as simple as changing the color of the numbers in the list usually involves some weird HTML/CSS workarounds.


Fortunately, by combining a couple of lesser-known CSS properties you can add numbers to your ordered lists that look just the way you want them to. In fact, after this tutorial, you’ll be able to change fonts, colors and nearly every other style attribute of numbers in lists.

The secret is twofold: first, hide the regular numbers entirely, then use the ::before pseudo-element to add the numbers back.

1. Add a class or ID name to the ordered list. It’s a good idea to identify each list that you want to create custom counters for:

<ol class="custom-counter">
   <li>This is the first item</li>
   <li>This is the second item</li>
   <li>This is the third item</li>
   <li>This is the fourth item</li>
   <li>This is the fifth item</li>
   <li>This is the sixth item</li>

If you simply use element selectors like ol or li, you’ll end up adding the same counter and counter design to every ordered list on the page.

2. Remove the style type from the list. First, you need to make sure that the browser isn’t adding its normal numbers. Applying the following style for the tag will do the trick:

.custom-counter {
    margin-left: 0;
    padding-right: 0;
    list-style-type: none;

This style also removes the indent that browsers add to the beginning of numbered lists. Because some browsers use margin and some use padding to indent lists, you need to set both the left padding and left margin values to 0.

3. Name the ‘counter-increment’ for list items. CSS provides a property named ‘counter-increment’. It enables you to assign a name to your counter. This doesn’t do much, except provide a way to identify the counter when using the ::before pseudo-element, which we’ll look at in the next step. Here’s some basic code to provide a name for the counter:

.custom-counter li {
    counter-increment: step-counter;

In this example, ‘step-counter’ doesn’t mean anything special, it’s not a CSS value or anything. It’s just a name we’ll use in the next step. You could use any name here, step, counter, or even bottles-of-root-beer-on-the-wall.

4. Use the ::before pseudo-element to add a counter numbers and style them:

.custom-counter li::before {
    content: counter(step-counter);
    margin-right: 5px;
    font-size: 80%;
    background-color: rgb(200,200,200);
    color: white;
    font-weight: bold;
    padding: 3px 8px;
    border-radius: 3px;

The ::before pseudo-element enables you to insert content before an element. In this case, it will insert content before a list item. You use the CSS content property to tell the browser what content it should place at the beginning of the list item. This could be actual words, or something generated automatically by the browser.

Here we’re using the counter( ) value, which works by giving counter( ) the name of the identifier provided by the counter-increment property. Remember, in step 2, we named the counter-increment ‘step-counter’ by providing that name to the counter, we’re telling the browser to use a counter for each list item. That counter is increased by 1 for each list item, so we end up with the number 1 before the first list item, the number 2 before the second list item and so on.

Of course, that’s what browsers normally do. However, using the ::before pseudo-element we can also style those numbers, something that’s not possible with regular numbered list items. In fact, the rest of the properties in this style are just to make the counter look cool like give it a background color, make the corners curved, change the font color, and so on. This style shows you just some of the ways you can customize the appearance of the numbers in your ordered lists. There’s plenty more you can do, so feel free to use all the CSS you know to create interesting, fun and beautiful ordered lists.

You can find a complete, working example, of this technique on CodePen.

Read more about the CSS counter-increment.

TR/css3-content/#counters; the ::before pseudo-element at http://www.w3.org/TR/CSS2/

And also read more about generate.html#before-after-content; and the content property.