Multiple CSS Counters Not Working as Expected

Multiple CSS counters not working as expected

There are 2 problems here:

  1. The direct parent of the first counted element should contain all the other counted elements. In your case, the first counted element is a td in a row, so its parent is a tr but all the other counted elements have their own parents of tr (which are siblings of the parent of the first counted element). So to fix this I think you have to set the class on the tr and count it there.

  2. The counter-reset and counter-increment can be overridden, that means if at one tr, you need to use counter-reset and counter-increment for more than 1 counter variable, you need to put them on the same declaration (space-separated) for counter-reset and counter-increment.

From 2 points above, here is the code it should be:

HTML:

<table class="tasksteps">
<thead>
<tr>
<td>TaakStep</td>
<td>Risk</td>
<td>Measure</td>
</tr>
</thead>
<tbody>
<tr class="taskstep">
<td class="taskstep t1">Step 1</td>
<td></td>
<td></td>
</tr>
<tr class="taskstep risk">
<td class="taskstep t2">Step 2</td>
<td class="risk">Risk 1</td>
<td></td>
</tr>
<tr class="risk">
<td class="t3"></td>
<td class="risk">Risk 2</td>
<td></td>
</tr>
<tr class="taskstep risk">
<td class="taskstep t2">Step 3</td>
<td class="risk">Risk 3</td>
<td></td>
</tr>
<tr class="taskstep risk">
<td class="taskstep t2">Step 4</td>
<td class="risk">Risk 4</td>
<td></td>
</tr>
<tr class="risk">
<td class="t4"></td>
<td class="risk">Risk 5</td>
<td class="measure">Measure 1</td>
</tr>
<tr>
<td class="t5"></td>
<td></td>
<td class="measure">Measure 2</td>
</tr>
<tr>
<td class="t5"></td>
<td></td>
<td class="measure">Measure 3</td>
</tr>
<tr>
<td class="t5"></td>
<td></td>
<td class="measure">Measure 4</td>
</tr>
<tr class="risk">
<td class="t3"></td>
<td class="risk">Risk 6</td>
<td></td>
</tr>
<tr class="risk">
<td class="t4"></td>
<td class="risk">Risk 7</td>
<td class="measure">Measure 5</td>
</tr>
</tbody>
</table>

CSS:

  table.tasksteps {
counter-reset: tasksteps;
}
tr.taskstep {
counter-reset: risks;
counter-increment: tasksteps;
}
tr.risk {
counter-reset: measures;
counter-increment: risks;
}
tr.taskstep.risk {
counter-reset: risks measures;
counter-increment: tasksteps risks;
}
td.measure {
counter-increment: measures;
}

td.taskstep:before {
content: counter(tasksteps) '. ';
}

td.risk:before {
content: counter(tasksteps) '.' counter(risks) '. ';
}

td.measure:before {
content: counter(tasksteps) '.' counter(risks) '.' counter(measures) '. ';
}

Updated Demo.

CSS counter increment does not work as expected

Its because you have applied counter-reset: h3counter in the wrong place i.e. h2:before. You will need to apply counter-reset: h3counter to the <h2> tag not its :before

h1 {  counter-reset: h2counter;}
h2 { counter-reset: h3counter;}
h2:before { content: counter(h2counter) ".\0000a0\0000a0"; counter-increment: h2counter;}
h3:before { content: counter(h2counter) "." counter(h3counter) ".\0000a0\0000a0"; counter-increment: h3counter;}
<h1>  XXXX</h1><h2>  YYYY</h2><h3>  ZZZZZZ</h3><h3>  ZZZZZZ</h3><h3>  ZZZZZZ</h3><h2>  YYYY</h2><h3>  ZZZZZZ</h3><h3>  ZZZZZZ</h3><h3>  ZZZZZZ</h3>

More counters in CSS

Change from:

body {
counter-reset: figcounter;
counter-reset: head2counter;
}

To:

body {
counter-reset: figcounter head2counter;
}

Why?

Because the counter-reset and counter-increment can be overridden.
So if you have to use counter-reset and counter-increment for
more than 1 element counter variable, you need to put them on the same declaration for counter-reset and counter-increment, with a space separating them.
In this case you only need to put the counter-reset property


body {  counter-reset: figcounter head2counter;}.fig:before {  counter-increment: figcounter;  content: "Fig. " counter(figcounter)": ";  font-weight: bold;}.figreset {  counter-reset: figcounter;}.head2:before {  counter-increment: head2counter;  content: counter(head2counter)" ";}.head2reset {  counter-reset: head2counter;}
<h1>Article title</h1><h2 class="head2">Services</h2><img src="http://www.google.com/about/company/images/company-products.png" width="200" /><span class="fig">Google services</span><h2 class="head2">E-mail clients</h2><h2 class="head2">Others</h2><img src="http://4.bp.blogspot.com/-JOqxgp-ZWe0/U3BtyEQlEiI/AAAAAAAAOfg/Doq6Q2MwIKA/s1600/google-logo-874x288.png" width="200" /><span class="fig">Google logo</span><br /><img src="http://thenextweb.com/wp-content/blogs.dir/1/files/2013/02/google_chrome.png" width="200" /><span class="fig">Chrome</span>

Counter Increment is not starting properly

You need to omit the first topic and increment from the second one otherwise you will increment the counter twice before the first display:

h4.heading_numberlist {
margin-top: 12.0pt;
margin-right: 0in;
margin-bottom: 3.0pt;
margin-left: 0in;
page-break-after: avoid;
font-size: 12.0pt;
font-family: "Arial", sans-serif;
color: black;
font-weight: bold;
}

h4.heading_numberlist::before {
content: counter(list-number, upper-alpha) '. ';
}

.topic:not(:first-child) {
counter-increment: list-number;
}
<div class="topic nested3">
<h4 class="heading_normal">Care</h4>
</div>
<div class="topic nested3">
<h4 class="heading_numberlist">Services</h4>
</div>
<div class="topic nested3">
<h4 class="heading_numberlist">Tests</h4>
</div>
<div class="topic nested3">
<h4 class="heading_numberlist">Number</h4>
</div>

Why does only one counter work when both are specified in body?

It's because you are declaring two counter-reset on the body tag. It will automatically default to the second one. In order to have two (or more) counter-resets, use one counter-reset with a space separated list:

body{
counter-reset: testA testB;
}

p::before{
counter-increment: testA;
content: counter(testA) ": ";
}

span::before{
counter-increment: testB;
content: counter(testB) ": ";
}
<p>P one</p>
<p>P two</p>
<span>Span one</span>
<span>Span two</span>

CSS counter-reset does not work inside pseudo elements

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.

Wrong numbering with css counters

The reason it works as intended in the second section (without the div's) but doesn't in the fist section is due to counter scope. According to the W3C:

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.

In the second half of the html, the h3s and h4s are siblings, therefore, the counter-reset defined on the h3 applies to the following h4 siblings. In the first part of the html, the h4s are not descendants nor siblings of the h3s, therefore, the counter-rest has no effect on them since they're out of scope.

The other thing is, if counter-reset is not defined in a given scope, it assumes a value of 0 each time you counter-increment or refer to the counter in a content rule, which explains why you're getting all 1s in the first part of the html:

If 'counter-increment' or 'content' on an element or pseudo-element refers to a counter that is not in the scope of any 'counter-reset', implementations should behave as though a 'counter-reset' had reset the counter to 0 on that element or pseudo-element.


If you have to wrap things in divs, I would:

  1. Define a counter-reset for the chapters counter on body, so that it's not assumed 0 each time you use a counter-increment.

  2. Either nest the h4s under their parent h3s (which is not cool) or make them siblings to ensure they're in the right scope.


New HTML:

<div>
<h3>dddd</h3>
<h4>dddd</h4>
<h4>dddd</h4>
</div>
<div>
<h3>dddd</h3>
<h4>dddd</h4>
<h4>dddd</h4>
</div>

Addition to CSS:

body {
counter-reset: chapter;
}

http://jsfiddle.net/myajouri/QpG9d/

CSS counter-increment not incrementing

The reason it doesn't work is because the h2 is in a sub-level (it has a parent that h3 doesn't).

This works:

<div> <!-- h2's first parent - also h3's first parent -->
<h2>Fifth section</h2>
<h3>Fifth section, first subsection</h3>
<h3>Fifth section, first subsection</h3>
</div>

This works:

<div> <!-- h2's first parent - h3's parent (not first) -->
<h2>Fifth section</h2>

<div>
<h3>Fifth section, first subsection</h3>
</div>

<div>
<h3>Fifth section, first subsection</h3>
</div>
</div>

This doesn't:

<div>
<div> <!-- h2's first parent - wait, there's no h3s in sub-levels! -->
<h2>Fifth section</h2>
</div>

<h3>Fifth section, first subsection</h3>
<h3>Fifth section, first subsection</h3>
</div>


Related Topics



Leave a reply



Submit