【问题标题】:CSS counter does not increment for <h2><h2> 的 CSS 计数器不会增加
【发布时间】:2016-06-19 08:58:18
【问题描述】:

我正在制作一个多列、CSS 编号的 TOC,如下所示:

| 1. TOC Level-1    | 2. TOC Level-1    |
| 1.1 TOC Level-2   | 2.1 TOC Level-2   |
| 1.2 TOC Level-2   | 2.2 TOC Level-2   |
| 1.3 TOC Level-2   | 3. TOC Level-1    |
                    | 3.1 TOC Level-2   |

由于 CSS 列是不可控的,因此使用 JS 和浮动“列”类完成包装。

这是我遵循的示例: http://www.2ality.com/2012/01/numbering-headingshtml.html

这是我使用的 CSS:

body {} .column {
  border: 2px dotted grey;
  float: left;
  width: 40%;
}
.menu-item:hover {
  cursor: pointer;
  color: blue;
}
.sub-nav-content {
  counter-reset: toc1;
}
h1 {
  counter-reset: toc2;
}
h1:before {
  counter-increment: toc1;
  content: counter(toc1)". ";
}
h2:before {
  counter-increment: toc2;
  content: counter(toc1)"." counter(toc2)" ";
}
<div class="sub-nav">
  <div class="sub-nav-content">
    <div class="column">
      <a class="menu-item"><h1>TOC entry level1</h1></a>
      <a class="menu-item"><h2>TOC entry level2</h2></a>
      <a class="menu-item"><h2>TOC entry level2</h2></a>
      <a class="menu-item"><h2>TOC entry level2</h2></a>
    </div>
    <div class=column>
      <a class="menu-item"><h1>TOC entry level1</h1></a>
      <a class="menu-item"><h2>TOC entry level2</h2></a>
      <a class="menu-item"><h2>TOC entry level2</h2></a>
      <a class="menu-item"><h1>TOC entry level1</h1></a>
      <a class="menu-item"><h2>TOC entry level2</h2></a>
      <a class="menu-item"><h2>TOC entry level2</h2></a>
      <a class="menu-item"><h2>TOC entry level2</h2></a>
    </div>
  </div>
</div>

不知何故,我无法让 2 级计数器递增。

【问题讨论】:

  • 不,他们不会...CSS 计数器高度 依赖于结构。当您包装第二个“列”时,您会重新开始计数。
  • 谢谢@Paulie_D。实现我需要的最佳方式是什么?
  • 感谢@Mo 调查
  • @MarcSmits:无需更改您的换行结构。只需更改内部结构,将h1h2 放在a 下。应该这样做。

标签: html css multiple-columns css-counter


【解决方案1】:

解决方案:

您可以通过稍微调整您的 HTML 和 CSS 来使用 CSS 计数器来实现这一点。首先,将a 放在h1h2 中,而不是相反。其次,在h1h2 级别增加计数器,但使用a:before 来显示编号。因此,该号码也将具有:hover(因为它现在是a 的一部分)。

演示:

body {} .column {
  border: 2px dotted grey;
  float: left;
  width: 40%;
}
.menu-item:hover {
  cursor: pointer;
  color: blue;
}
.sub-nav-content {
  counter-reset: toc1;
}
h1 {
  counter-reset: toc2;
}
h1 {
  counter-increment: toc1;
}
h1 a:before {
  content: counter(toc1)". ";
}
h2 {
  counter-increment: toc2;
}
h2 a:before {
  content: counter(toc1)"." counter(toc2)" ";
}
<div class="sub-nav">
  <div class="sub-nav-content">
    <div class="column">
      <h1><a class="menu-item">TOC entry level1</a></h1>
      <h2><a class="menu-item">TOC entry level2</a></h2>
      <h2><a class="menu-item">TOC entry level2</a></h2>
      <h2><a class="menu-item">TOC entry level2</a></h2>
    </div>
    <div class=column>
      <h1><a class="menu-item">TOC entry level1</a></h1>
      <h2><a class="menu-item">TOC entry level2</a></h2>
      <h2><a class="menu-item">TOC entry level2</a></h2>
      <h1><a class="menu-item">TOC entry level1</a></h1>
      <h2><a class="menu-item">TOC entry level2</a></h2>
      <h2><a class="menu-item">TOC entry level2</a></h2>
      <h2><a class="menu-item">TOC entry level2</a></h2>
    </div>
  </div>
</div>

原始问题的原因:

以下是您的结构(简化)。您正在做的是在h1 级别使用counter-resettoc2,但这个h1 嵌套在a 下方。

<div class="sub-nav">
  <div class="sub-nav-content">
    <div class="column">
      <a class="menu-item"><h1>TOC entry level1</h1></a>
      <a class="menu-item"><h2>TOC entry level2</h2></a>
      <a class="menu-item"><h2>TOC entry level2</h2></a>
      <a class="menu-item"><h2>TOC entry level2</h2></a>
    </div>
  </div>
</div>

根据W3C Specs,CSS 计数器的作用域和继承如下:

  • 当前元素获取其父级或兄弟级拥有的所有计数器。 (反继承
  • 继承计数器的值来自其上一个兄弟(或)父级。 (价值继承

这里,由于toc1 计数器在.sub-nav-content 级别重置,.column 元素都获取计数器,所有.menu-item 元素及其伪元素也获取它(从它们自己的父级) .当counter-increment 用于h1:before 时,它会增加从其父级得到 的计数器的值,因此直到.sub-nav-content 的所有元素都知道计数器的存在及其当前值。因此每个h1 都能够正确地递增它。

toc2 仅在h1 级别重置。这意味着.sub-nav-content、.column.menu-item 中没有人知道这个计数器的存在。只有h1 和它的孩子知道。因此,当遇到 h2 元素时,UA 会查看他们是否已经拥有该 toc2 计数器,因为他们没有它,所以 new toc2 在每个 h2 处创建计数器,并且它们会递增。因此它们的值将永远只有 1 而不是别的。

【讨论】: