W3docs

CSS counter-reset Property

Use CSS counter-reset property to define and initialize one or more CSS counters. Try counter-reset property examples! Learn with W3docs.

The counter-reset property creates one or more CSS counters and sets each of them to a starting value. Despite the name, its main job is to initialize a counter so it can be used later — it does not just zero out an existing counter, it brings the counter into existence in the current scope.

CSS counters are variables maintained by the browser whose values can be incremented by CSS rules to track how many times they are used. They make it possible to number sections, chapters, list items, or any repeated element entirely in CSS, with no markup changes or JavaScript.

A counter is only useful as part of a trio of properties:

  • counter-reset — creates the counter and gives it a start value (this page).
  • counter-increment — adds to the counter's value, usually once per matching element.
  • content — displays the counter's value through the counter() or counters() function, typically inside a ::before pseudo-element.

This page covers the syntax of counter-reset, how counter scope works, numbering nested sections, using negative and custom start values, and the values the property accepts.

How it works

Each counter-reset declaration takes a counter name you make up (for example section) followed by an optional integer start value:

/* "section" counter created, starts at 0 */
counter-reset: section;

/* "section" counter created, starts at 5 */
counter-reset: section 5;

/* multiple counters in one declaration */
counter-reset: chapter 0 page 1;

If you leave out the number, the counter starts at 0. The first matching element then runs counter-increment before content reads it, so a counter that starts at 0 and increments by 1 displays as 1 on the first element — which is usually what you want.

Scope matters. A counter created with counter-reset is scoped to the element it is declared on and that element's descendants and following siblings. This is what lets you reset a sub-counter for every section: putting counter-reset: subsection on each h2 gives every section its own fresh subsection counter. The nested-numbering example below relies on this behavior.

Initial Valuenone
Applies toAll elements.
InheritedNo.
AnimatableNo.
VersionCSS2
DOM Syntaxobject.style.counterReset = "section" ;

Syntax

counter-reset: none | name number | initial | inherit;

The name is an identifier you choose, and number is an optional integer (it can be negative). You can list several name number pairs in one declaration to create multiple counters at once.

Example: setting a counter with JavaScript

counter-reset is also reachable from the DOM as element.style.counterReset. Click "Try it" to reset the section counter to 5, so the headings renumber starting from 6.

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      h2::before {
        counter-increment: section;
        content: "Book " counter(section) ". ";
      }
    </style>
  </head>
  <body>
    <p>Click the "Try it" button to set the counter-reset property:</p>
    <button onclick="myFunction()">Try it</button>
    <h2>HTML Tutorials</h2>
    <h2>JavaScript Tutorials</h2>
    <h2>CSS Tutorials</h2>
    <script>
      function myFunction() {
        document.body.style.counterReset = "section 5";
      }
    </script>
  </body>
</html>

Example with a negative increment (counting down)

Negative numbers are allowed both as start values and on counter-increment. Here the counter is created at 0 and the increment is -1, so each heading counts down: -1, -2, -3, -4.

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      body {
        /* create "my-counter", start at 0 */
        counter-reset: my-counter;
      }
      h2::before {
        /* decrease "my-counter" by 1 on each h2 */
        counter-increment: my-counter -1;
        content: "Section " counter(my-counter) ". ";
      }
    </style>
  </head>
  <body>
    <h2>HTML Tutorial</h2>
    <h2>CSS Tutorial</h2>
    <h2>JavaScript Tutorial</h2>
    <h2>PHP Tutorial</h2>
  </body>
</html>

Example with numbered sections and subsections

This is the most common real-world use of counter-reset: nested numbering like 1.1, 1.2, 2.1. The subsection counter is reset on every h2, so each section restarts its subsection numbering from 1. Without that per-h2 reset, subsections would keep climbing across the whole document.

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      body {
        /* Set "section" to 0 */
        counter-reset: section;
      }
      h2 {
        /* Set "subsection" to 0 */
        counter-reset: subsection;
      }
      h2::before {
        counter-increment: section;
        content: "Book " counter(section) ": ";
      }
      h3::before {
        counter-increment: subsection;
        content: counter(section) "." counter(subsection) " ";
      }
    </style>
  </head>
  <body>
    <h2>HTML</h2>
    <h3>HTML Basics</h3>
    <h3>HTML Templates</h3>
    <h3>HTML References</h3>
    <h3>HTML Tags</h3>
    <h2>CSS</h2>
    <h3>CSS Basics</h3>
    <h3>CSS References</h3>
    <h3>CSS Advanced</h3>
    <h3>CSS Guides</h3>
    <h3>CSS Selectors</h3>
    <h3>CSS Properties</h3>
  </body>
</html>

Values

ValueDescription
noneCounters are not incremented.
name numberName defines the name of the counter to reset. Number defines the value to reset the counter to on each occurrence of the element. Defaults to 0 if not specified.
initialSets the property to its default value.
inheritInherits the property from its parent element.

Common gotchas

  • Nothing shows on its own. counter-reset only creates the counter. You still need counter-increment to advance it and content: counter(name) to display it. A page with only counter-reset renders no numbers.
  • counter-reset vs counter-set. counter-reset creates a counter in the current scope; the newer counter-set only changes the value of a counter that already exists and never creates a new scope. Reach for counter-reset when you want numbering to restart inside a section.
  • Increment runs before display. Because the increment on a ::before happens before content is read, a counter starting at 0 with +1 shows 1 on the first element. Start at a different value if you need a different first number.
  • Counters are not inherited. The property's value is not inherited, but the counter itself is visible to descendants and following siblings through scoping — that is what makes nested numbering work.

Browser support

counter-reset is part of CSS2 and is supported in all modern browsers, including Chrome, Firefox, Safari, Edge, and Opera.

Practice

Practice
What is the CSS 'counter-reset' property used for?
What is the CSS 'counter-reset' property used for?
Was this page helpful?