简体   繁体   中英

Where should counter-reset be used when automatically numbering headings with CSS counters?

I want to automatically number the headings with multiple levels of hierarchy in an HTML document using CSS. The examples I have found on the internet make extensive use of counter-reset, but I suspect this is often an incorrect use of counter-reset because it does not work for me under any configuration I have tested.

The h3 counter (subsection) should reset at each new h2.

Consider the following simple code example:

 body { counter-reset: section subsection; }.countheads>h2::before { counter-increment: section; content: counter(section, upper-roman); counter-reset: subsection; }.countheads>h3::before { counter-increment: subsection; content: counter(section, upper-roman) "." counter(subsection); }
 <body> <div class="countheads"> <h1> Main title </h1> <h2> Wuhhh </h2> <h3> First point </h3> <h3> Second point </h3> <h3> Third point </h3> <h2> Whoa </h2> <h3> First point </h3> <h3> Second point </h3> <h3> Third point </h3> </div> </body>

The expected behavior is that subsections in section II start again at 1, as in II.1, II.2.

If I change the counter-reset statement to counter-set, I get the desired result:

 body { counter-reset: section subsection; }.countheads > h2::before { counter-increment: section; content: counter(section, upper-roman); counter-set: subsection; }.countheads > h3::before { counter-increment: subsection; content: counter(section, upper-roman) "." counter(subsection); }
 <body> <div class="countheads"> <h1> Main title </h1> <h2> Wuhhh </h2> <h3> First point </h3> <h3> Second point </h3> <h3> Third point </h3> <h2> Whoa </h2> <h3> First point </h3> <h3> Second point </h3> <h3> Third point </h3> </div> </body>

With some syntax highlighters, the counter-set statement is marked red, implying an error, and yet it does what I want it to. But why doesn't counter-reset work in this case?

You need to reset inside the h2 and no the pseudo element:

 body { counter-reset: section subsection; }.countheads > h2::before { counter-increment: section; content: counter(section, upper-roman); } /*.countheads > h2 + h3: use this selector in case you have an issue with Firefox */.countheads > h2 { counter-reset: subsection; }.countheads > h3::before { counter-increment: subsection; content: counter(section, upper-roman) "." counter(subsection); }
 <body> <div class="countheads"> <h1> Main title </h1> <h2> Wuhhh </h2> <h3> First point </h3> <h3> Second point </h3> <h3> Third point </h3> <h2> Whoa </h2> <h3> First point </h3> <h3> Second point </h3> <h3> Third point </h3> </div> </body>

counter-set will do the same because

The value to set the counter to on each occurrence of the element. Defaults to 0 if not specified. If there isn't currently a counter of the given name on the element, the element will create a new counter of the given name with a starting value of 0 ref

In your case, the counter already exist so it will not get created.


From the specification :

The counter-reset property instantiates new counters on an element and sets them to the specified integer values.

And

The counter-increment and counter-set properties manipulate the value of existing counters . They only instantiate new counters if there is no counter of the given name on the element yet.

And more important

The scope of a counter therefore starts at the first element in the document that instantiates that counter and includes the element's descendants and its following siblings with their descendants.

So if you use counter-reset you wil create an instance with a scope limited to the pseudo element but using counter-set will simply modify the already instanciated counter on the upper level having a different scope.

To make a kind of analogy with programming language

int i = 0;
function a() {
   i = 0; /* this is counter-set */
}
function b() {
   int i = 0; /* this is counter-reset */
}

body { counter-reset: section subsection; }.countheads>h2::before { counter-increment: section; content: counter(section, upper-roman); counter-reset: subsection; }.countheads>h3::before { counter-increment: subsection; content: counter(section, upper-roman) "." counter(subsection); }

Main title

Wuhhh

First point

Second point

Third point

Whoa

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM