For better or for worse, we're not talking about counting visits to your site here. With that illusion shattered, CSS2 expands upon the familiar list (<li>) counting through generated content, allowing you to completely customize the type and behavior of the counter, and also, apply counting to just about any element you fancy. You can break counting into multiple nested levels, increment the counter in ways other than sequential etc. For XML documents where you don't want to be adding extraneous counters to the document, this can be very useful. Counters is a rather deep subject, so I'll only be covering the basics here. Also, it seems at the moment only Opera 7.5+ supports counters- not even Firefox 1.0 (and IE6+ of course) made the cut.

To set up a counter in CSS2, we rely on the following two properties:

  • counter-reset: Name of the counter (identifier) followed by an optional integer (default is 0 if non present). The integer specifies at what number the counter begins at.
  • counter-increment: Name of counter (identifier) followed by an optional integer (default is 1 if non present) The integer specifies by how much the counter is incremented each time. The default increment is 1. Zero and negative integers are allowed.

Here's a typical example that turns H2 and H3 elements into "Chapters" and "Sections" counters:

H2:before {
    content: "Chapter " counter(chapter) ". ";
    counter-increment: chapter;  /* Add 1 to chapter */
    counter-reset: section;      /* Set section to 0 */
H3:before {
    content: counter(chapter) "." counter(section) " ";
    counter-increment: section;

<h2>JavaScript Basics</h2>
<h3>Event handlers</h3>


The result looks like (screenshot):

Study the style sheet for a while- it combines both counter and string content to create the above. The integers are missing from the counter values, since without one specified, the default is used (0 for counter-reset, 1 for counter-increment).

Changing the counter-reset and counter-increment values

Now lets see a similar example, but one that lists only the "odd" sections. Take a look at this:

H2:before {
    content: "Chapter " counter(chapter) ". ";
    counter-increment: chapter;  /* Add 1 to chapter */
    counter-reset: section -1;      /* Set section to -1 */
H3:before {
    content: counter(chapter) "." counter(section) " ";
    counter-increment: section 2;

Notice how I set "counter-reset" for section to -1 and its increment value to 2. Since the counter is incremented first before the counting begins, in order to display the odd sections, I need to set the intial counter value to -1, so -1+2=1, 1+2=3 etc.

Resetting multiple counters

You can reset multiple counters at once inside counter-reset instead of just one:

H2{ counter-reset: section 2 subsection 8 }

Here both "section" and "subsection" are reset as a result.

Changing the type of counter

You can pick the type of counter displayed from a list of styles other than the default "decimal." Basically, all values of the CSS property "list-style-type" is suported here:

Values for list-style-type
disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-alpha | lower-latin | upper-alpha | upper-latin | hebrew | armenian | georgian | cjk-ideographic | hiragana | katakana | hiragana-iroha | katakana-iroha | none | inherit

Enter one of the above values into the optional second parameter of the counter property:

counter(name, 'list-style-type')

Here are a few examples:

H2:before{ content: counter(chapter, upper-latin) ". " }
H3:before{ content: counter(section, upper-roman) " - " }
P:before{ content: counter(myparah, katakana) }
DIV.mydiv:before{ content: counter(myspan, lower-alpha) " " }