Search

Automatically numbering headings via CSS

This post shows you how to number HTML headings with CSS. That is, given the following HTML.
<h1>My Article</h1>
<h2>Introduction</h2>
<h3>Rationale</h3>
<h2>Background</h2>
With the proper CSS, the above will be displayed as
My Article
 Introduction
 Rationale
 Background
Number the headings
To number the headings, we need the CSS construct counter. A counter is an integer variable for which there are there operations: reset, increment, read (in CSS content). To achieve the result shown above, the following CSS suffices:
body {
counter-reset: h2counter;
}
h1 {
counter-reset: h2counter;
}
h2:before {
contentcounter(h2counter) ".\0000a0\0000a0";
counter-increment: h2counter;
counter-reset: h3counter;
}
h3:before {
contentcounter(h2counter) "." counter(h3counter) ".\0000a0\0000a0";
counter-increment: h3counter;
}
Comments:
·         The above CSS resets the counter for the first numbering level called h2counter when it enters the body. Just to be safe, we reset it again at h
·         The pseudo-class :before allows us to insert content before the inside of a tag.
·         The character \0000a0 is a non-breaking space in CSS. Hence there are always two non-breaking spaces after the last dot of each heading number.
Switch off numbering for some headings
Sometimes we want a single heading to not be numbered. The following CSS does not number headings that have a class nocount.
body {
counter-reset: h2counter;
}
h1 {
counter-reset: h2counter;
}

h2:before {
contentcounter(h2counter) ".\0000a0\0000a0";
counter-increment: h2counter;
counter-reset: h3counter;
}
hnocount:before {
contentnone;
counter-incrementnone;
}

h3:before {
contentcounter(h2counter) "." counter(h3counter) ".\0000a0\0000a0";
counter-increment: h3counter;
}
hnocount:before {
contentnone;
counter-incrementnone;
}
We follow each counter clause with a non-counter version that becomes active in the presence of the class nocount and prevents the counter from being displayed and incremented.
Non-numbered headings by default
If you want to be able to choose between all headings being numbered and no headings being numbered, you have two options:
1.       Numbering is on by default: You can switch it off, e.g. by putting a class nocount in a surrounding tag. That can be achieved by replacing the single selector
hnocount:before
with two selectors:
.nocount h2:before, hnocount:before
2.       Numbering is off by default: Then you prefix the :before rules with a condition, e.g. whether the class countheads is present in a surrounding tag:
.countheads h2:before
The CSS shown below is a variation of idea #2: Switch on numbering if a sibling tag of h2 has a class countheads. The general sibling combinator ~ (tilde) lets us do that:
body {
counter-reset: h2counter;
}
h1 {
counter-reset: h2counter;
}

.countheads ~ h2:before {
contentcounter(h2counter) ".\0000a0\0000a0";
counter-increment: h2counter;
}
hnocount:before {
contentnone;
counter-incrementnone;
}
h2 {
counter-reset: h3counter;
}

.countheads ~ h3:before {
contentcounter(h2counter) "." counter(h3counter) ".\0000a0\0000a0";
counter-increment: h3counter;
}
hnocount:before {
contentnone;
counter-incrementnone;
}
Conclusion

We have seen how to automatically count headings in HTML via CSS and how to conditionally switch it off in some places. You can download a demo file (view online) on GitHub.

No comments:

Post a Comment