Make it Count with CSS Counters

February 09, 2014 | 6 Minute Read

Often I've found myself in a spot where I've needed to style an ordered list in a way that I just couldn't do with CSS. So I either had to live with it as it was or get tricky with JavaScript or something to create a custom list with the necessary markup. Then I stumbled across CSS Counters and that all changed.

CSS Counters are very similar to variables in other languages. You have to set the counter to zero for the element containing your list items and then increment it over the set which can be any tag. They don’t have to be used in an HTML list. Then using CSS generated content you can loop out whatever content you like. You are still bound to a single element because you’ll have to use a pseudo element but it helps to give you more control to style things consistently across browsers.

Here’s a Basic Example

This is the markup that I’ll be using:

<div class="counterItems">
    <div>This is an Item Here</div>
    <div>This is Another Item Here</div>
    <div>This is Yet Another Item Here</div>
    <div>This is Even Another Item Here</div>
</div>

First, Set Counter to Zero

First I have to set a counter variable to zero on the container element by doing something like this:

.counterItems {
    counter-reset: myCount; 
}

Next, Increment the Counter and Set Generated Content

Then I have to increment the count and set up the generated content for the items. In this case I’m setting it to the count plus a period and a paren:

.counterItems div:before {
    counter-increment: myCount; 
    content: counter(myCount)".) ";
}

The Demo

This is what the result looks like:

This is an Item Here
This is Another Item Here
This is Yet Another Item Here
This is Even Another Item Here

Making it Look Better

So, now that we have the incremented numbering in place, we can make it look how ever we want.

Squares

.counterSquares div:before {
    border-radius: 25px;
    counter-increment: squaresCount; 
    content: counter(squaresCount);
    display: block;
    float: left;
    height: 25px;
    line-height: 25px;
    margin: 7px 10px 0 0;
    text-align: center;
    width: 25px;
}
This is an Item Here
This is Another Item Here
This is Yet Another Item Here
This is Even Another Item Here

Circles

.counterCircles div:before {
    border-radius: 25px;
    counter-increment: circlesCount; 
    content: counter(circlesCount);
    display: block;
    float: left;
    height: 25px;
    line-height: 25px;
    margin: 7px 10px 0 0;
    text-align: center;
    width: 25px;
}
This is an Item Here
This is Another Item Here
This is Yet Another Item Here
This is Even Another Item Here

These are just a couple of examples but really you are only bound by your imagination on how you can style these things.

Use Nested Counters to Make a Table of Contents List

CSS Counters can be nested within each other. We can use this functionality do some pretty cool and complex stuff like create a unique table of contents.

The CSS

.tableOfContents ol { 
    counter-reset: tcCount; 
    list-style: none; 
} 

.tableOfContents li:before { 
    counter-increment: tcCount; 
    content: counters(tcCount, "."); 
    display: inline-block; 
    margin-right: 20px; 
    text-align: right; 
    width: 80px; } 

.tableOfContents > ol > li:before { 
    content: "Part " counter(tcCount); 
} 

.tableOfContents > ol ol { 
    font-size: 75%; 
    margin-bottom: 20px; 
}

The HTML

<ol>
    <li>
        This is the 1st Part
        <ol>
            <li>This is a section</li>
            <li>This is a section</li>
            <li>This is a section</li>
        </ol>
    </li>
    <li>
        This is the 2nd Part
        <ol>
            <li>This is a section</li>
            <li>This is a section</li>
            <li>This is a section</li>
        </ol>
    </li>
    <li>
        This is the 3rd Part
        <ol>
            <li>This is a section</li>
            <li>This is a section</li>
            <li>This is a section</li>
        </ol>
    </li>
</ol>

The Demo

  1. This is the 1st Part
    1. This is a section
    2. This is a section
    3. This is a section
  2. This is the 2nd Part
    1. This is a section
    2. This is a section
    3. This is a section
  3. This is the 3rd Part
    1. This is a section
    2. This is a section
    3. This is a section

Browser Support:

ie8 and above Chrome 31 and above Fire Fox 26 and above Safari 5.1 and above

CSS Counters have good browser support working in all modern browsers. Not supported in Internet Explorer 7 and below.


Sources