Lesson 78 +10 XP

Nested Counters

Nested Counters

Counters can nest: numbering like "1", "1.1", "1.1.2", just like book sections.

The setup

body {
  counter-reset: section;       /* top-level */
}
section {
  counter-reset: subsection;   /* every section resets a child counter */
}
section h2::before {
  counter-increment: section;
  content: counter(section) ". ";
}
section h3::before {
  counter-increment: subsection;
  content: counter(section) "." counter(subsection) " ";
}

When you enter a <section>, subsection resets to 0. When an h3 increments it you get "1.1", "1.2" within that section.

counters(): dots string

Combine parent + child values in one call:

li::marker {
  content: counters(list-item, ".") " ";
}

counters(name, sep) joins all ancestors' values with the separator.

Real example: nested list

ul {
  counter-reset: toc;
  list-style: none;
}
li::before {
  counter-increment: toc;
  content: counters(toc, ".") " ";
}

TL;DR

  • Reset a counter inside a container to get "fresh" numbering per block.
  • counter(section) "." counter(subsection) builds "1.1".
  • counters(name, ".") auto-builds the whole dotted chain.
  • Perfect for outlines, docs, and to-do trees.