CSS counters are used to give automatic numbering, whether it’s for lists or headings.
If you want your lists to auto-generate numbers or alphabets, CSS counters make it possible.
It’s great feature in CSS that let you automatically generate numbering or lettering for elements like lists, headings, or custom sections — without writing numbers manually.
With counters, you can easily show numbers, Roman numerals, or even alphabets for ordered content.
A CSS counter is like a variable maintained by the browser.
You can:
- Reset a counter (start from 0).
- Increment it (add 1 for each element).
- Display it using the
content
property in::before
or::after
.
In simple terms → CSS counters let you auto-generate numbers or letters for elements, without manually writing them.
Syntax of CSS Counters
counter-reset
→ Creates or resets a counter.counter-increment
→ Increases the counter value.counter(name, style)
→ Displays the counter with a specific style (decimal, roman, alpha, etc).
body {
counter-reset: section; /* Start a counter named 'section' */
}
h2::before {
counter-increment: section; /* Add 1 every time h2 appears */
content: "Section " counter(section, decimal) ": "; /* Show the number */
}
Common CSS Counter Styles
CSS supports multiple counter styles (like list-style-type
). Some useful ones are:
decimal
→ 1, 2, 3decimal-leading-zero
→ 01, 02, 03upper-roman
→ I, II, IIIlower-roman
→ i, ii, iiiupper-alpha
→ A, B, Clower-alpha
→ a, b, c
Let me show you how counters work: Step by Step
Step 1 – Create the counter
.blockCont{ // this will only apply to all h3 tag under class="blockCont"
padding:30px;
background-color:#f7f7f7;
counter-reset: myCounter;
}
or you can add common for all h3 tag
body{
counter-reset: myCounter;
}
Step 2 – Increment the counter when an element appears
h3 {
counter-increment: myCounter; /* Each h2 increases myCounter by 1 */
}
Step 3 – Display the counter
h3::before {
content: "" counter(myCounter) ": ";
font-weight: bold;
}
Below example show demo where all <h3>
tag under class=”blockCont” showing numbering. If you want to show all h3 tag not specific for class=”blockCont” then add counter-reset:myCounter to body tag.
.blockCont{
padding:30px;
background-color:#f7f7f7;
counter-reset: myCounter;
}
h3 {
counter-increment: myCounter;
}
h3::before {
content: "" counter(myCounter) ": ";
font-weight: bold;
}
<div class="blockCont" style="padding:100px 30px; background-color:#F2CA01; ">
<h3>Heading one</h3>
<h3>Heading two</h3>
<h3>Heading three</h3>
<h3>Heading four</h3>
</div>
Output:
Heading one
Heading two
Heading three
Heading four
Different Counter Formats
By default, counters show plain numbers (1, 2, 3). But CSS allows different styles like Roman numerals, alphabets, or even leading zeros.
Here are some useful styles with examples:
1. Decimal Numbers (1, 2, 3)
The most common numbering style in CSS counters is decimal, which displays numbers in the standard 1, 2, 3… sequence.
This is the default style for ordered lists (<ol>
).
ol.decimal {
list-style: none;
counter-reset: num;
}
ol.decimal li {
counter-increment: num;
}
ol.decimal li::before {
content: counter(num, decimal) ". ";
}
<div style="padding:100px 30px; background-color:#F2CA01; ">
<ol class="decimal">
<li>Item one</li>
<li>Item two</li>
<li>Item three</li>
</ol>
</div>
Output
- Item one
- Item two
- Item three
2. Decimal with Leading Zeros (01, 02, 03)
Sometimes, you may want to display number with two digits (01, 02, 03) instead of single digits (1, 2, 3). This makes your lists look uniform and is useful for steps, timelines, or numbering with a professional touch.
This style is achieved using decimal-leading-zero
in CSS.
ol.zero {
list-style: none;
counter-reset: num;
}
ol.zero li {
counter-increment: num;
}
ol.zero li::before {
content: counter(num, decimal-leading-zero) " → ";
}
<div style="padding:100px 30px; background-color:#F2CA01; ">
<ol class="zero">
<li>Item one</li>
<li>Item two</li>
<li>Item three</li>
</ol>
</div>
Output:
- Item one
- Item two
- Item three
3. Upper Roman Numerals (I, II, III)
Roman numerals are often used in books, outlines, research papers, and formal documents. With CSS counters, you can easily switch your list style from normal decimal numbers to Roman numerals.
When you set the list style to upper-roman
, your list items will be displayed in capital Roman numerals such as I, II, III, IV, V…
ol.roman {
list-style: none;
counter-reset: num;
font-size:20px;
}
ol.roman li {
counter-increment: num;
line-height:36px;
}
ol.roman li::before {
content: counter(num, upper-roman) ". ";
}
<div style="padding:100px 30px; background-color:#F2CA01; ">
<ol class="roman">
<li>Item one</li>
<li>Item two</li>
<li>Item three</li>
</ol>
</div>
Output:
- Item one
- Item two
- Item three
4. Lower Roman Numerals (i, ii, iii)
Lower Roman numerals are the small-letter version of Roman numbering. Instead of showing numbers in uppercase (I, II, III), they display in lowercase (i, ii, iii, iv, v…).
ol.lroman {
list-style: none;
counter-reset: num;
}
ol.lroman li {
counter-increment: num;
}
ol.lroman li::before {
content: counter(num, lower-roman) ") ";
}
<div style="padding:100px 30px; background-color:#F2CA01; ">
<ol class="lroman">
<li>Item one</li>
<li>Item two</li>
<li>Item three</li>
</ol>
</div>
Output:
- Item one
- Item two
- Item three
5. Uppercase Alphabet (A, B, C)
Instead of numbers, CSS counters can also display alphabets. With the upper-alpha
style, the list items are labeled with capital letters: A, B, C, D, and so on.
ol.alpha {
list-style: none;
counter-reset: num;
font-size:20px;
}
ol.alpha li {
counter-increment: num;
}
ol.alpha li::before {
content: counter(num, upper-alpha) ") ";
}
<div style="padding:100px 30px; background-color:#F2CA01; ">
<ol class="alpha">
<li>Item one</li>
<li>Item two</li>
<li>Item three</li>
</ol>
</div>
Output:
- Item one
- Item two
- Item three
6. Lowercase Alphabet (a, b, c)
Just like uppercase letters (A, B, C), CSS counters can also display lowercase alphabets using the lower-alpha
style. In this format, your list items will be labeled with small letters: a, b, c, d…
ol.lalpha {
list-style: none;
counter-reset: num;
font-size:20px;
}
ol.lalpha li {
counter-increment: num;
}
ol.lalpha li::before {
content: counter(num, lower-alpha) ". ";
}
<div style="padding:100px 30px; background-color:#F2CA01; ">
<ol class="lalpha">
<li>Item one</li>
<li>Item two</li>
<li>Item three</li>
</ol>
</div>
- Item one
- Item two
- Item three
7. Mixed / Nested Numbering (1.1, 1.2, 2.1)
Sometimes, you don’t just need simple numbering — you want multi-level numbering (like in books, outlines, or documentation). This style is called nested counters.
.blockCont {
counter-reset: chapter; /* outer counter */
}
h2 {
counter-reset: section; /* reset section inside each chapter */
counter-increment: chapter;
}
h2::before {
content: "Chapter " counter(chapter) ": ";
}
h3 {
counter-increment: section;
}
h3::before {
content: counter(chapter) "." counter(section) " ";
}
<div class="blockCont" style="padding:100px 30px; background-color:#F2CA01; ">
<h2>Introduction</h2>
<h3>Background</h3>
<h3>Scope</h3>
<h2>Getting Started</h2>
<h3>Installation</h3>
<h3>Setup</h3>
<h2>Advanced Topics</h2>
<h3>Custom Counters</h3>
<h3>Nested Lists</h3>
</div>
Output :