CSS Counters

By  on  

Counters.  They were a staple of the Geocities / early web scene that many of us "older" developers grew up with;  a feature then, the butt of web jokes now.  CSS has implemented its own type of counter, one more sane and straight-forward than the ole "hit counter."  CSS counters allow for simple CSS-based incrementing and display of a number for generated content.  Let's have a quick look at how CSS counters work!

Initializing the CSS Counter

For the sake of semantics, let's displays a series of slides using <OL> and <LI> elements for our counter example.  The first step is resetting the counter, providing the specific counter a name initializing it to 0:

ol.slides {
	counter-reset: slideNum;
}

The counter name slideNum will be used throughout the example.

Incrementing the CSS Counter

To increment the counter, use the counter-increment property and the counter name created in the first step:

ol.slides > li {
	counter-increment: slideNum;
}

Each counter-increment call continues to increment the counter.  Be aware that you must use > in your selector if you have nested lists so that your list numbering doesn't get incremented at the wrong points.

Using the Counter Value

Counters aren't much good if you can't display them (just like in 1995!), so the counter() command will output the counter value when used with the content property:

ol.slides li:after {
	content: "[" counter(slideNum) "]";
}

Oddly enough, counters can also be nested by using a second argument to counter, which will act as a separater:

/* assume this HTML:

<ol class="toc">
	<li>Intro</li>
	<li>Topic
		<ol>
			<li>Subtopic</li>
			<li>Subtopic</li>
			<li>Subtopic</li>
		</ol>
	</li>
	<li>Topic
		<ol>
			<li>Subtopic</li>
			<li>Subtopic</li>
			<li>Subtopic</li>
		</ol>
	</li>
	<li>Closing</li>		
</ol>
*/

ol.toc, ol.toc ol {
	counter-reset: toc;
}
ol li {
	counter-increment: toc;
}
.toc li:before {
	content: "(Item " counters(toc, ".") ")";
}

/* visible page "output"

<ol class="toc">
	<li>(Item 1)Intro</li>
	<li>(Item 2)Topic
		<ol>
			<li>(Item 2.1)Subtopic</li>
			<li>(Item 2.2)Subtopic</li>
			<li>(Item 2.3)Subtopic</li>
		</ol>
	</li>
	<li>(Item 3)Topic
		<ol>
			<li>(Item 3.1)Subtopic</li>
			<li>(Item 3.2)Subtopic</li>
			<li>(Item 3.3)Subtopic</li>
		</ol>
	</li>
	<li>(Item 4)Closing</li>		
</ol>
*/

As you can probably tell, counters could be incredibly helpful when it comes to basic count display up to a table of contents display.

After you get over the initial giggle of the the word counter, you start to realize that they can be quite useful.  In most cases, you'll use counters with :after and :before pseudo-elements, unless you dedicate empty elements to their contents.  I've seen counters used in broadcast slides, slideshows, and documentation.  Do you use counters for anything else?

Recent Features

  • By
    CSS Animations Between Media Queries

    CSS animations are right up there with sliced bread. CSS animations are efficient because they can be hardware accelerated, they require no JavaScript overhead, and they are composed of very little CSS code. Quite often we add CSS transforms to elements via CSS during...

  • By
    An Interview with Eric Meyer

    Your early CSS books were instrumental in pushing my love for front end technologies. What was it about CSS that you fell in love with and drove you to write about it? At first blush, it was the simplicity of it as compared to the table-and-spacer...

Incredible Demos

  • By
    Use Custom Missing Image Graphics Using Dojo

    A few months back I posted an article about how you can use your own "missing image" graphics when an image fails to load using MooTools and jQuery. Here's how to do the same using Dojo. The HTML We'll delegate the image to display by class...

  • By
    Using jQuery and MooTools Together

    There's yet another reason to master more than one JavaScript library: you can use some of them together! Since MooTools is prototype-based and jQuery is not, jQuery and MooTools may be used together on the same page. The XHTML and JavaScript jQuery is namespaced so the...

Discussion

  1. This is amazing… and I’m shocked at the browser support (IE8+ and all modern browsers).

  2. Cool! CSS is totally awesome! Thanks for this article.

  3. mary

    OMG I’m a bit obsessed with tables of contents and numbering section headings. I didn’t know it’s possible with CSS.

    Thank you for this!

  4. Nice :-)
    Thank you very much!

  5. Albert

    CSS counter tidbits and helpful links in a gist
    https://gist.github.com/aristretto/5614914

  6. Super cool post. Really creative and potentially beneficial. Thanks for that!

  7. Henning

    Ummm demo link seems to be wrong?

  8. Nice blog, thanks for the tutorial and example! The only problem is that the CSS-generated content is not accessible to users of some assistive technology such as screen readers.

  9. Nessi

    Haha – “Counter” is a little bit misleading. Thought I will see a Countdown on the demo page, but got it now. Counting the elements with CSS. Brilliant! :)

  10. didn’t know it’s possible with CSS.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!