2

我正在尝试计算不是常规列表的元素。

更容易用代码解释: Fiddle

我或多或少无法控制 html。


相反,DOM 看起来像这样:

 <div class="body">
  <div><p class="numlist" >first text</p></div>
  <div><p class="numlist">second text</p></div>
  <div><p class="numlist">third text</p></div>
  <!-- Only here for only here in demonstrative purpose -->
  <div class="should-reset"><p>Start a new counter for the inlines</p></div>
  <div><p class="numlist depth">first text</p></div>
  <div><p class="numlist depth">second text</p></div>
  <div><p class="numlist depth">third text</p></div>
  <!-- Only here for only here in demonstrative purpose -->
  <div class="should-reset"><p>Want to reset the standard counter</p></div>
  <div><p class="numlist reset" >first text</p></div>
  <div><p class="numlist">second text</p></div>
  <div><p class="numlist">third text</p></div>      
</div>

我想要的结果是这样的:

1. list one
2. list one
3. list one
     1. list two
     2. list two
     3. list two
1. list three
2. list three
3. list three    

但是列表三总是这样,就像计数器永远不会重置一样:

1. list three
4. list three
5. list three    
4

3 回答 3

0

您的计数器重置<div><p class="numlist reset" >first text</p></div>不会重置原始计数器,因为在元素上发生的计数器重置仅适用于在该元素及其兄弟级别定义的计数器。您不是重置原始计数器,而是创建一个同名的新计数器,该计数器的范围仅限于 P 元素(以及存在的任何后续兄弟或子元素)。

这可以通过替换"counters(standard," AND ")你写的地方看到counter(standard)

.body {
  counter-reset: standard inline;  
}

div > p.numlist::before {
  counter-increment: standard;
  content: counters(standard," AND ") ". ";
}

div > p.numlist.depth::before {
  counter-increment: inline;
  content: counter(inline) ". ";
  margin-left: 50px;
}

.should-reset {
  color: red;
}

div > p.numlist.reset {
  counter-reset: standard;
}
<div class="body">
  <div>
    <p class="numlist" >first text</p>
  </div>
  <div>
    <p class="numlist">second text</p>
  </div>
  <div>
    <p class="numlist">third text</p>
  </div>
<!-- Only here for only here in demonstrative purpose -->
  <div class="should-reset">
    <p>
      Start a new counter for the inlines
    </p> 
  </div>
  <div>
    <p class="numlist depth" depth>first text</p>
  </div>
  <div>
    <p class="numlist depth" depth>second text</p>
  </div>
  <div>
    <p class="numlist depth" depth>third text</p>
  </div>
  <!-- Only here for only here in demonstrative purpose -->
    <div class="should-reset">
    <p>
    Want to reset the standard counter
    </p> 
  </div>
  <div>
    <p class="numlist reset" >first text</p>
  </div>
  <div>
    <p class="numlist">second text</p>
  </div>
  <div>
    <p class="numlist">third text</p>
  </div>
  
</div>

虽然,正如您在上面看到的,该counters()函数显示了在当前范围内可见的给定名称的所有当前计数器,而不仅仅是该名称的最本地定义的计数器,没有办法让 acounter-reset达到并从更高的位置重置实例范围。

这不是浏览器错误(与问题下方评论中的猜测相反)。来自https ://drafts.c​​sswg.org/css-lists-3/#nested-counters :

计数器是“自嵌套”的;在从其父元素继承同名计数器的元素上实例化一个新计数器会创建一个同名的新计数器,嵌套在现有计数器内。这对于像 HTML 中的列表这样的情况很重要,其中列表可以嵌套在列表中任意深度:不可能为每个级别定义唯一命名的计数器。counter() 函数仅检索元素上给定名称的最内层计数器,而 counters() 函数使用包含该元素的给定名称的所有计数器。

因此,计数器的范围从文档中实例化该计数器的第一个元素开始,并包括该元素的后代及其后续兄弟姐妹及其后代。但是,它不包括在计数器范围内的任何元素,这些元素由元素的较晚同级上的计数器重置创建的具有相同名称的计数器,从而允许此类显式计数器实例化模糊那些较早的同级。

如果您无法更新 HTML,并且这些<div class="should-reset">元素仅用于提供信息,那么您不能仅使用 CSS 来执行此操作。它需要类似:has()伪类的东西,所以不是你的

div > p.numlist.reset {
  counter-reset: standard;
}

它需要

div:has(> p.numlist.reset) {
  counter-reset: standard;
}

然而,据我所知,W3C CSS 工作组没有立即将:has()伪类添加到“ live ”选择器配置文件中,我怀疑这会很快完成,因为它可能会显着降低性能。(Selectors Level 4 草稿只包含has():在“快照”配置文件中,适用于 JS 方法querySelector()目前还没有主流浏览器支持它。)

请注意,即使在这种情况下div:has(> p.numlist.reset) {counter-reset: standard;}(只有在实时配置文件中采用它才会起作用:has()),仍然会创建一个名为“标准”的新嵌套计数器,而不是重置您创建的那个

.body {
  counter-reset: standard inline;  
}
于 2019-10-15T19:18:41.540 回答
0

为什么不简单地使用<ol>标签?

备注/补充:在我发布答案后,这个要求被添加到问题中:“我或多或少无法控制 html。”

.inset {
  margin-left: 20px;
}
<ol>
  <li>
    first text
  </li>
  <li>
    second text
  </li>
  <li>
    third text
  </li>
  </ol>

  <ol class="inset">
    <li>
      first text
    </li>
    <li>
      second text
    </li>
    <li>
      third text
    </li>
  </ol>
  
  <ol>
    <li>
      first text
    </li>
    <li>
      second text
    </li>
    <li>
      third text
    </li>
  </ol>

于 2017-02-17T12:03:48.713 回答
0

.body {
  counter-reset: standard;  
}

.should-reset {
  counter-reset: standard;
  color: red;
}

.numlist::before {
  counter-increment: standard;
  content: counter(standard) ". ";
}

.numlist.depth::before {
  margin-left: 50px;
}
<div class="body">
  <div><p class="numlist" >first text</p></div>
  <div><p class="numlist">second text</p></div>
  <div><p class="numlist">third text</p></div>
  <div class="should-reset"><p>Start a new counter for the inlines</p> </div>
  <div><p class="numlist depth" depth>first text</p></div>
  <div><p class="numlist depth" depth>second text</p></div>
  <div><p class="numlist depth" depth>third text</p></div>
  <div class="should-reset"><p>Want to reset the standard counter</p> </div>
  <div><p class="numlist" >first text</p></div>
  <div><p class="numlist">second text</p></div>
  <div><p class="numlist">third text</p></div>
</div>

升级版:

.body {
  counter-reset: standard;  
}

.body div:nth-child(3n + 1) {
  counter-reset: standard;
}

.numlist::before {
  counter-increment: standard;
  content: counter(standard) ". ";
}

.numlist.depth::before {
  margin-left: 50px;
}
<div class="body">
  <div><p class="numlist reset" >first text</p></div>
  <div><p class="numlist">second text</p></div>
  <div><p class="numlist">third text</p></div>
  <div><p class="numlist depth" depth>first text</p></div>
  <div><p class="numlist depth" depth>second text</p></div>
  <div><p class="numlist depth" depth>third text</p></div>
  <div><p class="numlist" >first text</p></div>
  <div><p class="numlist">second text</p></div>
  <div><p class="numlist">third text</p></div>
</div>

于 2017-02-17T12:29:21.073 回答