11

The following CSS counter example does not work as expected. The counter for sub-headings should reset after every main heading:

body {
  font: smaller sans-serif;
  counter-reset: h1 h2;
}
h1:before {
  counter-reset: h2;
  content: counter(h1) ". ";
  counter-increment: h1;
}
h2:before {
  content: counter(h1) "." counter(h2) ". ";
  counter-increment: h2;
}
<h1>Heading</h1>
<h2>Sub-heading</h2>
<h2>Sub-heading</h2>
<h1>Heading</h1>
<h2>Sub-heading</h2>
<h2>Sub-heading</h2>

However, the following works as expected:

body {
  font: smaller sans-serif;
  counter-reset: h1 h2;
}
h1:before {
  content: counter(h1) ". ";
  counter-increment: h1;
}
h1 {
  counter-reset: h2;
}
h2:before {
  content: counter(h1) "." counter(h2) ". ";
  counter-increment: h2;
}
<h1>Heading</h1>
<h2>Sub-heading</h2>
<h2>Sub-heading</h2>
<h1>Heading</h1>
<h2>Sub-heading</h2>
<h2>Sub-heading</h2>

My question is, why does counter-reset not work inside pseudo elements?

pschueller
  • 4,362
  • 2
  • 27
  • 50
Salman A
  • 262,204
  • 82
  • 430
  • 521
  • How very odd, I have just been messing around with this and cant find a reason. Also had a brief look at the documentation and cant see anything either. – Ruddy Feb 26 '15 at 15:45

1 Answers1

12

I believe this is a scope problem. The docs state:

Counters are "self-nesting", in the sense that resetting a counter in a descendant element or pseudo-element automatically creates a new instance of the counter....

... The scope of a counter starts at the first element in the document that has a 'counter-reset' for that counter and includes the element's descendants and its following siblings with their descendants. However, it does not include any elements in the scope of a counter with the same name created by a 'counter-reset' on a later sibling of the element or by a later 'counter-reset' on the same element.

The way I understand this is that when you reset the counter a new instance of the counter is created on the parent element. If you do this on h1:before it gets created on that single <h1> element which is then immediately closed... hence you get no reset on the initial counter.

pschueller
  • 4,362
  • 2
  • 27
  • 50
  • 1
    Correct, it took me a while to get my head around this (I have also been reading the documentation). So it acts as if the `

    ` is the parent and starts a new counter instead of resetting the level up counter. +1

    – Ruddy Feb 26 '15 at 15:55
  • Yes, it didn't make it very clear at all. Just putting in this answer in that documentation would have saved us a lot of time! – Ruddy Feb 26 '15 at 15:58
  • To be fair, the spec caters to implementers more than authors. It's not meant to be author-friendly at all. Some of the level 3 and 4 modules are set to change this however. – BoltClock Feb 26 '15 at 16:02
  • Makes sense. But I don't get the part _"or by a later 'counter-reset' on the same element"_. How can you "later" reset a counter on the same element? – Salman A Feb 26 '15 at 17:08
  • I think all they are saying is that once you've reset the counter on the same element, the previous counter no longer applies. So in other words, a reset on the same element is "out of scope" of the first counter. – pschueller Feb 26 '15 at 18:37