Using CSS counter-increment with Custom Intervals

The CSS counter-increment property allows web developers to control numerical sequences on web pages without relying on JavaScript or manual markup. By appending an optional integer to the counter name—such as in counter-increment: my-counter 2—CSS increments the tracked value in specified steps rather than the default interval of one. This article explains the syntax, mechanics, and practical behavior of custom intervals using the counter-increment property.

The Syntax of Custom Increments

A CSS counter tracks numbers across elements matched by a selector. The counter-increment property accepts two main parameters: the name of the counter and an optional integer that specifies the step value.

selector {
  counter-increment: counter-name integer;
}

If the integer is omitted, browsers use a default value of 1. Specifying a custom integer instructs the rendering engine to modify the running total by that exact number every time the rule is applied to an element.

How counter-increment: my-counter 2 Works

When using the rule counter-increment: my-counter 2, the browser follows these sequential steps:

  1. Initialization: The counter is typically initialized using counter-reset: my-counter; on a parent element. Unless an initial starting number is provided, counter-reset defaults the counter value to 0.
  2. Step Calculation: Each time an element matching the selector is processed in the DOM order, the browser adds 2 to the current value of my-counter.
  3. Sequential Output: If three successive elements match the rule, their values will evaluate to 2, 4, and 6.

If the parent element initializes the counter at a specific offset, such as counter-reset: my-counter 1;, the increment will add 2 to that starting value, producing an odd sequence: 3, 5, 7, and so on.

Practical Implementation

To display the counter values, the counter must be output using the counter() function within a pseudo-element’s content property:

/* Parent container resets the counter */
.step-list {
  counter-reset: my-counter;
}

/* Each item increments the counter by 2 */
.step-list li {
  counter-increment: my-counter 2;
  list-style: none;
}

/* Display the number */
.step-list li::before {
  content: counter(my-counter) ". ";
  font-weight: bold;
}
<ul class="step-list">
  <li>First item (Displays: 2.)</li>
  <li>Second item (Displays: 4.)</li>
  <li>Third item (Displays: 6.)</li>
</ul>

Negative Intervals and Zero

The integer passed to counter-increment is not limited to positive numbers:

  • Negative Intervals: Supplying a negative integer, such as counter-increment: my-counter -1 or -2, decrements the counter by that value, enabling countdowns or reverse-ordered lists.
  • Zero Values: Passing 0 (e.g., counter-increment: my-counter 0) prevents the counter from changing its value for that specific element, which is useful when numbering only certain elements within a matched set.