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()orcounters()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 Value | none |
|---|---|
| Applies to | All elements. |
| Inherited | No. |
| Animatable | No. |
| Version | CSS2 |
| DOM Syntax | object.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
| Value | Description |
|---|---|
| none | Counters are not incremented. |
| name number | Name 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. |
| initial | Sets the property to its default value. |
| inherit | Inherits the property from its parent element. |
Common gotchas
- Nothing shows on its own.
counter-resetonly creates the counter. You still needcounter-incrementto advance it andcontent: counter(name)to display it. A page with onlycounter-resetrenders no numbers. counter-resetvscounter-set.counter-resetcreates a counter in the current scope; the newercounter-setonly changes the value of a counter that already exists and never creates a new scope. Reach forcounter-resetwhen you want numbering to restart inside a section.- Increment runs before display. Because the increment on a
::beforehappens beforecontentis read, a counter starting at0with+1shows1on 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.