How do CSS counters work?

南笙酒味 提交于 2021-01-28 14:06:40

问题


<!DOCTYPE html>
<html>

<head>
  <style>
    body {
      counter-reset: ele;
    }
    *::after {
      counter-increment: ele;
      content: "element count " counter(ele);
    }
  </style>
</head>

<body>

  <h1> h1 </h1>
  <h2> h2 </h2>
  <h2> h2 </h2>
  <h2> h2 </h2>

  <p><b> b </b> p</p>

  <br/>
  <br/>
  <br/>
  <br/>
  <br/>
  <br/>

</body>

</html>

In the above snippet:

  • It looks like all the <br/> tags getting ignored by CSS counters. The reason is?
  • In the above snippet, what are elements 7 and 8 representing?

回答1:


Explanation of the problem(s)

It looks like all the <br/> tags getting ignored by CSS counters. The reason is?

<br> tags, like other 'empty' elements, do support counters, but unfortunately, they don't have an ::after pseudo-element. Just like for instance <input> elements, you cannot pull this trick to generate content through CSS. Since incrementing the counter happens in this ::after pseudo-element in your snippet, the counter is not incremented for <br> element because br::after simply doesn't exist.

In the above snippet, what are elements 7 and 8 representing?"

The BODY and HTML tags. Since you use ::after, the counter is incremented and the content inserted at the end of those elements, after the other page content.

Half fix: Count the elements instead of the pseudo-elements

You can change the CSS slightly to increment the counter on the element itself, and only display the value in the pseudo-element.

<!DOCTYPE html>
<html>

<head>
  <style>
    body {
      counter-reset: ele;
    }
    * {
      counter-increment: ele;
    }
    *::after {
      content: "element count " counter(ele);
    }
  </style>
</head>

<body>

  <h1> h1 </h1>
  <h2> h2 </h2>
  <h2> h2 </h2>
  <h2> h2 </h2>

  <p><b> b </b> p</p>

  <br>
  <br>
  <br>
  <br>
  <br>
  <br>

</body>

</html>

The example above doesn't quite work yet, because it doesn't increment the counter when going up a level. This is because the counter was already incremented when the element was opened, and closing the HTML and the BODY doesn't increment the counter anymore.

Workaround: count pseudo-elements and empty elements

Possible ways to fix it even better: Increment the counter in the ::after after all, but add an extra piece of CSS that increments the counter for elements that don't have an ::after pseudo-element:

<!DOCTYPE html>
<html>

<head>
  <style>
    body {
      counter-reset: ele;
    }
    
    /* Increment the counter in the '::after' of non-empty elements. */
    *::after,
    /* And in the element itself for empty element. 
       List taken from https://developer.mozilla.org/en-US/docs/Glossary/Empty_element */
    link,track,param,area,command,col,base,meta,hr,source,img,keygen,br,wbr,colgroup,input
    {
      counter-increment: ele;
    }
    
    *::after {
      content: "element count " counter(ele);
    }
  </style>
</head>

<body>

  <h1> h1 </h1>
  <h2> h2 </h2>
  <h2> h2 </h2>
  <h2> h2 </h2>

  <p><b> b </b> p</p>

  <br>
  <br>
  <br>
  <br>
  <br>
  <br>

</body>

</html>

Maybe it's not perfect for every scenario, but your question seems to be more academical anyway. Anyway, I hope this explanation at least helps you understand why in your snippet those <br> elements don't seem to have a counter at all.



来源:https://stackoverflow.com/questions/34607940/how-do-css-counters-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!