Multiple CSS counters not working as expected

后端 未结 3 2069
遇见更好的自我
遇见更好的自我 2021-01-14 18:26

I am trying to create multiple levels of counters in a html table, but this is not working as I expected. The first counter works ok, but the next counters do not work. Some

相关标签:
3条回答
  • 2021-01-14 18:45

    CSS is designed to take advantage of the hierarchical nature of HTML, hence the "cascading" style sheets. The element structure of your table is linear and as such defeats the efficiency of the cascade. I understand that there are circumstances when you might not have control over the HTML structure of the document in which case a CSS kluge might be in order. Otherwise, I would suggest restructuring your elements to match the same hierarchy of the layout you're trying to achieve. MUCH simpler and more scalable code.

    HTML:

     <ul>
      <li class='taskstep'>Step 1</li>
      <li class='taskstep'>Step 2
        <ul>
          <li class='risk'>Risk 1</li>
          <li class='risk'>Risk 2</li>
        </ul>
      </li>
      <li class='taskstep'>Step 3
        <ul>
          <li class='risk'>Risk 3</li>
        </ul>
      </li>
      <li class='taskstep'>Step 4
        <ul>  
          <li class='risk'>Risk 4</li>
          <li class='risk'>Risk 5</li>
            <ul>  
              <li class='measure'>Measure 1</li>
              <li class='measure'>Measure 2</li>
              <li class='measure'>Measure 3</li>
              <li class='measure'>Measure 4</li>
            </ul>
          <li class='risk'>Risk 6</li>
          <li class='risk'>Risk 7</li>
        </ul>
      </li>
    </ul>
    

    CSS:

    ul{
      list-style-type: none;
      counter-reset: foo;
    }
    li:before{
      counter-increment: foo;
      content: counters(foo,".") ". ";
    }
    

    Demo

    0 讨论(0)
  • 2021-01-14 18:53

    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.

    0 讨论(0)
  • 2021-01-14 18:56

    I played a bit, and it seems the issue was resetting all the counters on the same line in the body.

    Here's the FIDDLE.

    CSS

    body {
      counter-reset: tasksteps risks measures;
    }
    table td {
      width: 120px;
      border: 1px solid black;
    }
    td.taskstep {
      counter-increment: tasksteps;
    }
    td.risk {
      counter-increment: 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) '. ';
          }
    
    0 讨论(0)
提交回复
热议问题