CSS — Counters
Numbering without touching HTML
CSS can count elements and inject numbers via generated content:
.steps {
counter-reset: step; /* create + zero a counter */
}
.steps li {
counter-increment: step; /* +1 per item */
}
.steps li::before {
content: counter(step); /* display the value */
}
<ol class="steps">
<li>Preheat oven</li>
<li>Mix ingredients</li>
<li>Bake</li>
</ol>
(Each li now shows 1, 2, 3 — no HTML changes, reorders renumber automatically.)
Styled number badges
The real payoff — design freedom native <ol> markers lack:
.steps { list-style: none; padding: 0; }
.steps li {
position: relative;
padding-left: 48px;
margin-bottom: 16px;
}
.steps li::before {
content: counter(step);
position: absolute;
left: 0; top: 0;
width: 32px; height: 32px;
background: #0d9488;
color: white;
border-radius: 50%;
display: grid;
place-items: center;
font-weight: 700;
}
(Teal circles with white numbers hanging left of each step.)
Custom formats
counter(step, upper-roman) /* I, II, III */
counter(step, lower-alpha) /* a, b, c */
counter(step, decimal-leading-zero) /* 01, 02 */
/* decorated content strings */
content: "Step " counter(step) " of " counter(total) ": ";
content: counter(step) ".";
Nested counting with counters()
Chapters/sections/subsections:
.doc { counter-reset: chapter; }
.chapter { counter-reset: section; }
.chapter > h2::before {
counter-increment: chapter;
content: counter(chapter) ". ";
}
.section h3::before {
counter-increment: section;
content: counter(chapter) "." counter(section) " "; /* 1.1, 1.2… */
}
counters(section, ".") does the same automatically through any depth:
.outline ul { counter-reset: sub; }
.outline li::before {
counter-increment: sub;
content: counters(sub, ".") " "; /* auto: 1, 1.1, 1.1.1 */
}
Resetting mid-document
Multiple independent lists need resets at each container (shown above on .steps) — otherwise numbering continues across them.
Where counters shine
- Step-by-step tutorials and recipes
- FAQ / how-to numbering that survives reordering
- Document outlines (h2/h3 numbering)
- Leaderboards, top-10 lists with custom badges
Limits: pseudo-element content only (not selectable text); screen readers may skip it — for essential numbering keep semantic
<ol>underneath.
Mini Practice
- Badge-numbered tutorial steps.
- Roman-numeral top-10 list.
- Two-level doc outline: "1." chapters, "1.1" sections.
- Three independent numbered lists on one page (proper resets).
- "Question 3 of 10:" pattern using two counters.
Next: multiple columns →
Related Topics
Frequently Asked Questions about Counters
What is Counters in CSS?
Counters is a fundamental concept in CSS. This lesson explains it step by step with clear examples, making it easy for beginners to understand.
How do I learn Counters?
Start by reading the explanation above, then try the code examples. Practice by modifying the examples and experimenting with different values. Hands-on practice is the best way to learn Counters.
Why is Counters important in CSS?
Counters is essential for CSS development. Understanding this concept will help you write better code and solve real-world problems more effectively.