Css counters are a convenient way to number nested lists, especially when they are dynamic. I just came across a bit of a gotcha (read. reminder) when using multple css counters in the same element.

Non-working code

I tried to use the counter-reset attribute multiple times on the same element, and got something that looked like this:

  • First Volume Name
    • First Chapter Name
    • Second Chapter Name
  • Second Volume Name
    • Third Chapter Name
    • Fourth Chapter Name

Obviously only one of the counter is being initialized. Here is the code for this failed attempt.

<style>
  ul.not-working{
    counter-reset: volume;
    counter-reset: chapter;
  }

  ul li.volume:before{
    counter-increment: volume;
    content: "Volume " counter(volume) ": ";
  }
  ul li.chapter:before{
    counter-increment: chapter;
    content: "Volume " counter(chapter) ": ";
  }
</style>

<ul class="not-working">
  <li class='volume'>
    First Volume Name
    <ul>
      <li class='chapter'>First Chapter Name</li>
      <li class='chapter'>Second Chapter Name</li>
    </ul>
  </li>
  <li class='volume'>
    Second Volume Name
    <ul>
      <li class='chapter'>Third Chapter Name</li>
      <li class='chapter'>Fourth Chapter Name</li>
    </ul>
  </li>
</ul>

Working Code

The problem is that css attributes not program instructions! Only one will be applied. The styles should be read.

<style>
  ul.working{
    counter-reset: volume chapter; /* all counters in same attributes */
  }

  ul li.volume:before{
    counter-increment: volume;
    content: "Volume " counter(volume) ": ";
  }
  ul li.chapter:before{
    counter-increment: chapter;
    content: "Volume " counter(chapter) ": ";
  }
</style>

And now our list looks correct:

  • First Volume Name
    • First Chapter Name
    • Second Chapter Name
  • Second Volume Name
    • Third Chapter Name
    • Fourth Chapter Name