Counter properties in CSS. What are they for and how do they work?

Asked

Viewed 598 times

10

I was recently studying CSS and discovered the counter-reset and the counter-increment, I just didn’t really understand the properties and I had some questions.

Doubts

  1. What good is counter-reset and the counter-increment in the CSS?
  2. Is there any real usefulness to these properties?
  3. Are supported by many browsers?
  4. How they really work?

2 answers

7


There are some very interesting forms of application for counter. One is to number pages, the other is to number items and sub-items from a list for example. But you can use to number chapters of an editorial and its sub-titles for example... Another simple application would be to number divs, as if they were an ordered list of divs.

Numbering UL and LI

First see this basic model to understand the concept.

Notice that in it I start the counter in UL, and in the ::after that UL I put the result inside the content. After that I use LI to increment the counter value. This means I will "count" how many LI exist in the DOM with CSS and plot this value in content of UL.

Now you put the number on the LI. For that you will put in the ::after das LI the same counter(teste), only now he’s in every LI it will display the element’s own index.

inserir a descrição da imagem aqui

See the code to better understand, I left the comments for you to better understand.

ul {
    /* inicia o contador aqui */
    counter-reset: teste;
}
ul::after {
    /* vai pegar o que vier do counter-increment das LIs e colocar aqui nesse after */
    content: counter(teste);
    font-weight: bold;
    color: red;
}
li {
    /* vai contar quantas LI tem no DOM dentro dessa UL */
    counter-increment: teste;
}
li::after {
    /* coloca na LI o próprio número que ela tem no index */
    content: " " counter(teste);
    color: green;
}
  <ul>
      <li>item 1</li>
      <li>item 2</li>
      <li>item 3</li>
      <li>item 4</li>
      <li>item 5</li>
  </ul>


Leaking List of Scope

This type of list is interesting, because it "bleeds the scopes" of the father and the order of the list is shared. What I mean is that we have here 3 OL and yet the order of the count is shared among all LI as if the OL was "ignored". This happens because we started the counter on body, and not in the OL

Notice that even all the OL having some LI inside, the alphabetical sequence follows as one thing only of the first LI of the first OL until the last LI of the latter OL. For example, the second group of LIs within the second OL begins in the letter D and not in the letter A

OBS: I used OL and LI, but could be DIVs and Ps quietly (but not semantically)

body {
  background: #333;
  counter-reset: mega-step mini-step;
}
ol {
  padding: 0;
}
ol li{
  counter-increment: mini-step;
  list-style:none;
}
ol li:before{
  content:counter(mini-step, lower-alpha) " ";
  background:darkred;
  color:white;
  padding:2px 5px;
  margin: 4px;
  font:14px/250% times new roman;
  border-radius: 100%;
  font-weight: bold;
}

section {
  width: 20%;
  float: left;
  margin: 20px;
  background: white;
  counter-increment: mega-step;
  padding: 5px;
  position: relative;
  
}
section:before {
  content: counter(mega-step, upper-roman);
  background:white;
  width:30px;
  position: absolute;
  left:0px; top:-20px;
  text-align: center;
  color:darkred;
  font: bold 20px times new roman;
}
<section>
  <ol>
    <li>começa no A</li>
    <li>LI 2 da OL 1</li>
    <li>LI 3 da OL 1</li>
  </ol>
</section>

<section>
  <ol>
    <li>Segue com D</li>
    <li>LI 2 da OL 2</li>
    <li>LI 3 da OL 2</li>
  </ol>
</section>

<section>
  <ol>
    <li>LI 1 da OL 3</li>
    <li>LI 2 da OL 3</li>
    <li>Última li de 3 OL = I</li>
  </ol>
</section>

In this example I used upper-roman to number the Sections with Roman numbers (I) and lower-alpha to sort the Kem alphabetical order (to). See that the second argument of counter is the style used for in counter.

content: counter(mega-step, upper-roman)
content:counter(mini-step, lower-alpha)

TIP: Here is a complete list of this Styles that you can use in the counter, are the same traditionally used in Sorted Lists and Unordered

https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-type


See example of list / sub-list

First you have to "start" the Counter in all the <ol>, and remove the default value from the Sorted List. Then <li> you make the increment of Counter in the Content. The cool thing here is that you have all the flexibility of CSS to customize your numbers etc. OBS: I left the comments in the CSS code

ol {
    counter-reset: section;  /* inicia um contador com valor 0 nome de "section" */             
    list-style-type: none;   /* remove o valor default da <ol> */ 
}

li::before {
    counter-increment: section; /* inclui o contado "section" com incremento de 1 */          
    content: counters(section, "-") ": ";  /* pega o valor do counter do pai e coloca um "-" depois da um espaço com os ": " e coloca o valor do counter do filho */
    color: red;
    font-size: 20px;
    font-family: sans-serife;
}

.custom-counter {
    margin: 0;
    padding: 0;
}
<div>
    <ol class="custom-counter">
        <li><b>RESUMO DE ATIVIDADES</b>
            <ol class="custom-counter">
                <li><b>SUB ATIVIDADES</b></li>
                <li><b>SUB ATIVIDADES</b></li>
            </ol>
        </li>
        <li><b>COMENTÁRIOS</b>
            <ol class="custom-counter">
                <li><b>SUB COMENTÁRIOS</b></li>
                <li><b>SUB COMENTÁRIOS</b></li>
            </ol>
        </li>
    </ol>
</div>


Numbering example divs 2 in 2 as the increment of 2 within the counter-increment

div {
    width: 100px;
    height: 100px;
    border: 1px solid;
    position: relative;
    display: inline-block;
    counter-increment: nDiv 2; /* começa o contador a partir de 2 e vai somando 2 a cada incremento */
}

div::before {
    content: counter(nDiv); /* mostra o valor do contador */
    position: absolute;
    top: 5px;
    left: 5px;
}
<div></div>
<div></div>
<div></div>
<div></div>


Here’s an example application for page numbering:

  @page {
    size: A4;  
    margin: 70pt 60pt 170pt;
    counter-increment: page;
    @bottom-center {
      content: "Page " counter(page);
    }
  }

Example of how to start counting by a certain number on a given page.

 @page { counter-increment: page } @page:first { counter-reset: page 9 }

The combination of both rules will reset the counter to the first page to 9. Then, for each page (including the first), it will increment the counter. This results in a counter value of 10 for the first page, 11 for the second and so on.

Source: https://www.tallcomponents.com/blog/css3-page-counter


About the browser support

Counter is a relatively old and widely accepted property, until IE8 already has support for it as you can see here: https://caniuse.com/#feat=css-counters

Reference and documentation

Here you can read more about the Counter https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Lists_and_Counters/Using_CSS_counters

  • Example customizing Predefined characters for the list, type a JSON list in CSS @counter-style sua-lista {&#xA; system: cyclic;&#xA; symbols: "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "☺️" "" "" "";&#xA; suffix: " ";&#xA;} https://codepen.io/argyleink/pen/rNmzGzW

5

The estate counter-reset creates or resets a CSS counter for a given value.

The estate counter-increment causes the value of the counter to be increased or decreased.

Take the example, where I say that meu_contador has initial value 0, and after each occurrence is always incremented +1. Note that the ::before allows inserting content before an element, in this case before an item in the list. The property content is to tell the browser that the content should be placed at the beginning of the HTML element.

<!DOCTYPE html>
<html>

<head>
  <style>
    body {
      /* definindo "meu_contador"  como 0 */
      counter-reset: meu_contador 0;
    }
    
    h2::before {
      /* Incrementado "meu_contador" como 1 */
      counter-increment: meu_contador 1;
      content: "Fruta " counter(meu_contador) ": ";
      color: black;
    }
    
    h1 {
      color: orange;
    }
    
    h2 {
      color: green;
    }
  </style>
</head>

<body>
  <h1>Lista de frutas:</h1>
  <h2>Uva </h2>
  <h2>Maçã</h2>
  <h2>Jabuticaba</h2>
  <h2>Pêra</h2>
  <h2>Banana</h2>
  <h2>Laranja</h2>

</body>

</html>

Syntax:

- counter-increment:

counter-increment: <custom-ident> <integer>

Where:

  • <custom-ident>:

    Is the counter name to increment.

  • <integer>:

    This is the value to add to the counter. If no default value is specified 1.

Example: counter-increment: exemplo_contador 2;

- counter-reset:

counter-reset: <custom-ident> <integer>

Where:

  • <custom-ident>:

    Is the name of the counter to reset.

  • <integer>:

    It is the value to reset the counter at each occurrence of the element. If no default value is specified it is 0.

Example: counter-reset: exemplo_contador 1;

To image below shows the version of the browsers that fully support the property:

Versão dos navegadores que suportam a propriedade

Reference:

MDN Web Docs

W3schools

Browser other questions tagged

You are not signed in. Login or sign up in order to post.