Make it Count with CSS Counters
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:
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;
}
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;
}
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
- This is the 1st Part
- This is a section
- This is a section
- This is a section
- This is the 2nd Part
- This is a section
- This is a section
- This is a section
- This is the 3rd Part
- This is a section
- This is a section
- This is a section
Browser Support:
CSS Counters have good browser support working in all modern browsers. Not supported in Internet Explorer 7 and below.