← Back toFront-end Tips

Number headings and subheadings automatically

Written byPhuoc Nguyen
14 Mar, 2021
It's a common approach to use the DOM APIs to find all headings on the page, and number each of them. This post introduces another way to do that with CSS only.
If you follow some search engine optimization (known as SEO) practices, you are adviced to use only one `h1` tag on the page. The single `h1` tag is used to display the main title. Hence, we will ignore the `h1` tag when numbering the headings.
Given the following markup:
<h2>Chapter 1</h2>

<h3>Section 1</h3>
<h4>Sub section A</h4>

<h3>Section 2</h3>
<h4>Sub section A</h4>
<h4>Sub section B</h4>

<h2>Chapter 2</h2>
It should produce the content as below:
1. Chapter 1

1.1. Section 1
1.1.1. Sub section A

1.2. Section 2
1.2.1. Sub section A
1.2.2. Sub section B

2. Chapter 2
We can archive it by using the CSS counter.
Going down from the `body` element, we will reset the counter for the first `h2`. The numbers are inserted before the content via the `::before` pseudo element:
h1 {
counter-reset: h2;
h2::before {
counter-increment: h2;
content: counter(h2) '. ';
The `counter-increment` property indicates that when we see the next `h2` tag, the number will be increased by one.
We continue using the same technique for `h3` tags. The number for a `h3` heading must be prefixed with the number of its parent `h2` tag:
h2 {
counter-reset: h3;
h3::before {
counter-increment: h3;
content: counter(h2) '.' counter(h3) '. ';
Here we use the `.` character to separate the numbers. If you want to number deeper headings such as `h4`, `h5`, then the CSS should look like as following:
h3 {
counter-reset: h4;
h4 {
counter-reset: h5;
h4::before {
counter-increment: h4;
content: counter(h2) '.' counter(h3) '.' counter(h4) '. ';
h5::before {
counter-increment: h5;
content: counter(h2) '.' counter(h3) '.' counter(h4) '.' counter(h5) '. ';

See also

Questions? 🙋

Do you have any questions? Not just about this specific post, but about any topic in front-end development that you'd like to learn more about? If so, feel free to send me a message on Twitter or send me an email. You can find them at the bottom of this page.
I have a long list of upcoming posts, but your questions or ideas for the next one will be my top priority. Let's learn together! Sharing knowledge is the best way to grow 🥷.

Newsletter 🔔

If you're into front-end technologies and you want to see more of the content I'm creating, then you might want to consider subscribing to my newsletter.
By subscribing, you'll be the first to know about new articles, products, and exclusive promotions.
Don't worry, I won't spam you. And if you ever change your mind, you can unsubscribe at any time.