Each element or pseudo-element has a set of counters in the scope of that element. Initial counters in the set are received from the element's parent and the preceding sibling. The counter values are received from the last descendent of the previous sibling, the last sibling, or the parent.
When an element declares a counter, the counter is nested inside the counter with the same name received from the parent. If the parent doesn't have a counter with the same name then the counter is added to the element's counters set as it is. A counter with the same name received from the previous sibling is removed from the counters set.
The counter()
function retrieves the innermost counter with the provided name. And the counters()
function retrieves the entire counter tree with the given name.
In the following example, we are demoing an inherited counter named primary
and a sibling counter named secondary
. All the <div>
elements display their counters using the counters()
function. Note that all the counters have been created using counter-reset
property, and none of the counters have been incremented.
<section>
counter-reset: primary 3
<div>A</div>
<div>B</div>
<div>C</div>
<div class="same-primary-name">D</div>
<span> counter-reset: primary 6</span>
<div>E</div>
<div class="new-secondary-name">F</div>
<span> counter-reset: secondary 5</span>
<div>G</div>
<div>H</div>
<div class="same-secondary-name">I </div>
<span> counter-reset: secondary 10</span>
<div>J </div>
<div>K</div>
<section></section>
</section>
/* create 'primary' counter on divs' parent */
section {
counter-reset: primary 3;
}
div::after {
content: " ('primary' counters: " counters(primary, "-", style)
", 'secondary' counters: " counters(secondary, "-", style) ")";
color: blue;
}
/* create new 'primary' counter */
.same-primary-name {
counter-reset: primary 6;
}
/* create 'secondary' counter on div 'F' */
.new-secondary-name {
counter-reset: secondary 5;
}
/* override the sibling 'secondary' counter */
.same-secondary-name {
counter-reset: secondary 10;
}
The section element initializes a counter named primary
with value 3
, and all the child <div>
s receive the inherited primary
counter. The element 'D' creates a new primary
(value 6
) counter which gets nested in the counter received from the parent, so the element has two counters named primary
with values 3
and 6
.
The element 'F' creates the secondary
(value 5
) counter for the first time, and it passes the counter to the next sibling 'G'. The element 'G' passes the counter to the next element 'H' and so on. Next, the element 'I' creates a new counter with the same name secondary
(value 10
), but it drops the secondary
(value 5
) counter received from the previous sibling 'H' and passes its own counter to 'J'.