Your counter-reset at <div><p class="numlist reset" >first text</p></div>
does not reset the original counter because a counter-reset that occurs at an element only applies to the counter defined at the level of that element and its siblings. Instead of resetting the original counter, you are creating a new counter of the same name, a counter whose scope is limited to the P element (and any subsequent siblings or children that exist).
This can be seen by substituting in "counters(standard," AND ")
where you wrote counter(standard)
:
.body {
counter-reset: standard inline;
}
div > p.numlist::before {
counter-increment: standard;
content: counters(standard," AND ") ". ";
}
div > p.numlist.depth::before {
counter-increment: inline;
content: counter(inline) ". ";
margin-left: 50px;
}
.should-reset {
color: red;
}
div > p.numlist.reset {
counter-reset: standard;
}
<div class="body">
<div>
<p class="numlist" >first text</p>
</div>
<div>
<p class="numlist">second text</p>
</div>
<div>
<p class="numlist">third text</p>
</div>
<!-- Only here for only here in demonstrative purpose -->
<div class="should-reset">
<p>
Start a new counter for the inlines
</p>
</div>
<div>
<p class="numlist depth" depth>first text</p>
</div>
<div>
<p class="numlist depth" depth>second text</p>
</div>
<div>
<p class="numlist depth" depth>third text</p>
</div>
<!-- Only here for only here in demonstrative purpose -->
<div class="should-reset">
<p>
Want to reset the standard counter
</p>
</div>
<div>
<p class="numlist reset" >first text</p>
</div>
<div>
<p class="numlist">second text</p>
</div>
<div>
<p class="numlist">third text</p>
</div>
</div>
While, as you see above, the counters()
function shows all the current counters of a given name visible from the current scope, not just the most locally defined counter of that name, there is no way for a counter-reset
to reach up and reset the instances from higher scopes.
This is not a browser bug (contrary to speculation in a comment beneath the question). From https://drafts.csswg.org/css-lists-3/#nested-counters :
Counters are “self-nesting”; instantiating a new counter on an element which inherited an identically-named counter from its parent creates a new counter of the same name, nested inside the existing counter. This is important for situations like lists in HTML, where lists can be nested inside lists to arbitrary depth: it would be impossible to define uniquely named counters for each level. The counter() function only retrieves the innermost counter of a given name on the element, whereas the counters() function uses all counters of a given name that contain the element.
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. 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, allowing such explicit counter instantiations to obscure those earlier siblings.
If you cannot update the HTML, and the <div class="should-reset">
elements are only there for informational purposes, you cannot do this with CSS alone. It would require something like like a :has() pseudo-class, so instead of your
div > p.numlist.reset {
counter-reset: standard;
}
it would require
div:has(> p.numlist.reset) {
counter-reset: standard;
}
However, as far as I know, there are no immediate pans by the W3C CSS Working Group to add the :has()
pseudo-class to the "live" selector profile, and I doubt that will be done anytime soon, as it could markedly slow performance. (The Selectors Level 4 draft only includes has():
in the "snapshot" profile, suitable for JS methods like querySelector()
, and at this time, no major browser even supports it for that, yet.)
Note that even in the case of div:has(> p.numlist.reset) {counter-reset: standard;}
(which would only work if :has()
is ever adopted in the live profile), one would still be creating a new nested counter named "standard", not resetting the one you created with
.body {
counter-reset: standard inline;
}