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
    Animated 3D Flipping Menu with CSS

    CSS animations aren't just for basic fades or sliding elements anymore -- CSS animations are capable of much more.  I've showed you how you can create an exploding logo (applied with JavaScript, but all animation is CSS), an animated Photo Stack, a sweet...

  • By
    Write Better JavaScript with Promises

    You've probably heard the talk around the water cooler about how promises are the future. All of the cool kids are using them, but you don't see what makes them so special. Can't you just use a callback? What's the big deal? In this article, we'll...

Incredible Demos

  • By
    CSS pointer-events

    The responsibilities taken on by CSS seems to be increasingly blurring with JavaScript. Consider the -webkit-touch-callout CSS property, which prevents iOS's link dialog menu when you tap and hold a clickable element. The pointer-events property is even more JavaScript-like, preventing: click actions from doing...

  • By
    Font Replacement Using Cufón

    We all know about the big font replacement methods. sIFR's big. Image font replacement has gained some steam. Not too many people know about a great project named Cufón though. Cufón uses a unique blend of a proprietary font generator tool...

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!