在下面的代码中,我需要使用HTML顶部的div
标记进行样式设置。如果没有div
标记,则hx
标记的大纲编号正确,但如果div
到位,则一切都完全错误。我需要this像this一样工作,但div
标记仍然存在,我需要它来处理具有不同ID的div。有什么想法吗?
body {counter-reset: h1}
h1 {counter-reset: h2}
h2 {counter-reset: h3}
h1:before {counter-increment: h1; content: counter(h1) ". "}
h2:before {counter-increment: h2; content: counter(h1) "." counter(h2) ". "}
h3:before {counter-increment: h3; content: counter(h1) "." counter(h2) "." counter(h3) ". "}
<div class="varies">
<h1>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h1>
</div>
<p>Morbi efficitur nibh metus, a vehicula mauris tristique ac. Duis ornare metus eget iaculis hendrerit.</p>
<h2>Morbi nisi lacus, ultricies sit amet turpis a, aliquet congue nulla.</h2>
<p>Duis eget facilisis nisl.</p>
<h3>Donec tincidunt purus quam, ut accumsan lorem hendrerit a.</h3>
<p>Aenean in mattis quam.</p>
<h3>Maecenas a nulla sit amet ligula facilisis tincidunt lacinia non enim.</h3>
<p>Aliquam dignissim turpis placerat, facilisis magna et, venenatis purus.</p>
<h2>Suspendisse tempus eu elit nec malesuada.</h2>
<p>In ut sollicitudin nisi. Praesent non porttitor ante, molestie scelerisque mauris.</p>
<h2>Vivamus eu turpis efficitur, ornare risus in, consectetur tellus.</h2>
<p>Cras pellentesque orci eu placerat mollis.</p>
<h1>Duis eu nulla et tellus porttitor auctor.</h1>
答案 0 :(得分:9)
通过查看W3C specs关于计数器创建,范围和继承的说法,可以详细解释行为的原因。
计数器重置: counter-reset属性在元素上创建新计数器。
计数器的范围:计数器的范围从文档中对该计数器进行“计数器重置”的第一个元素开始。
计数器继承:计数器及其值可以单独继承,可能来自不同的元素。如果元素具有前一个兄弟,则它必须继承所有兄弟的计数器。否则,如果元素具有父元素,则它必须继承所有父元素的计数器。否则,元素必须具有一组空的计数器。然后,该元素从文档顺序中紧接在前的元素继承计数器值。
在工作代码段(没有div
的代码段)中,会发生以下情况:
counter.h1
(添加了一个区别于元素的前缀)在body
创建(或重置),其初始值设置为0. body
中的每个元素都会获得counter.h1
。遇到第一个h1
时,counter.h1
的值会增加到1.当遇到下一个h1
时,它会从前一个元素继承计数器值,然后递增到2. / LI>
counter.h2
计数器在h1
元素处创建,值设置为0.此值对h1
的兄弟可见,并且它们都可以继承它。 h2
元素实际上都是h1
元素的兄弟元素,因此每个h2
元素都会继承已在{{1}创建的counter.h2
元素并且只增加其值。因此,当遇到第一个h1
时,h2
变为1,依此类推。counter.h2
元素类似,h2
元素也是h3
和h1
元素的兄弟元素,因此它们也继承h2
和{{ 1}}。这就是此样本中编号保持正确的原因。
counter.h1
counter.h2
现在让我们来看看不起作用的片段(body {counter-reset: h1}
h1 {counter-reset: h2}
h2 {counter-reset: h3}
h1:before {counter-increment: h1; content: counter(h1)". "}
h2:before {counter-increment: h2; content: counter(h1)"." counter(h2)". "}
h3:before {counter-increment: h3; content: counter(h1)"." counter(h2)"." counter(h3)". "}
中存在<!-- body creates counter.h1 and set to 0 -->
<h1>Heading 1 <!-- Inherits counter.h1 from parent, creates counter.h2 and set to 0 -->
<!-- ::before being a child inherits all counters from parent, increments counter.h1 to 1 and displays value -->
</h1>
<p>Paragraph</p>
<h2>Heading 2 <!-- Inherits counter.h1, counter.h2 from sibling, creates counter.h3 and set to 0 -->
<!-- ::before being a child inherits all counters from parent, increments counter.h2 to 1 and displays value -->
</h2>
<p>Paragraph</p>
<h3>Heading 3 <!-- Inherits counter.h1, counter.h2, counter.h3 -->
<!-- ::before being a child inherits all counters from parent, increments counter.h3 to 1 and displays value -->
</h3>
<p>Paragraph</p>
<h3>2nd Heading 3 <!-- Inherits counter.h1, counter.h2, counter.h3 -->
<!-- ::before being a child inherits all counters from parent, increments counter.h3 to 2 and displays value -->
</h3>
<p>Paragraph</p>
<h2>2nd Heading 2 <!-- Inherits counter.h1, counter.h2, counter.h3, resets counter.h3 to 0 -->
<!-- ::before being a child inherits all counters from parent, increments counter.h2 to 2 and displays value -->
</h2>
<p>Paragraph</p>
<h2>3rd Heading 2 <!-- Inherits counter.h1, counter.h2, counter.h3, resets counter.h3 to 0 -->
<!-- ::before being a child inherits all counters from parent, increments counter.h2 to 3 and displays value -->
</h2>
<p>Paragraph</p>
<h1>2nd Heading 1 <!-- Inherits counter.h1, counter.h2, counter.h3, resets counter.h2 to 0 -->
<!-- ::before being a child inherits all counters from parent, increments counter.h1 to 2 and displays value -->
</h1>
的片段。)
h1
创建div
,但这只能由h1
的兄弟姐妹(其中没有)继承。counter.h2
元素时,UA会尝试在h1
选择器中增加h2
的值。但是counter.h2
父级不会继承:before
,因此h2
也不会。因此counter.h2
将创建自己的h2:before
并增加到1. h2:before
元素也无法继承counter.h2
,因为计数器是由h2
(counter.h2
的子项)创建的。因此,每次遇到h2:before
时,都会在其h2
内创建一个新计数器并递增。这就是为什么所有h2
都显示为 1.1 的原因。 :before
个元素都不知道h2
,也不会增加它们,这就是为什么它们显示为 1.0.x 的原因。 h3
,因为它是counter.h2
元素创建的,它是所有counter.h3
元素的兄弟。这就是h2
正确递增的原因。
h3
counter.h3
这个问题的理想解决方案是首先在主体本身重置所有3个计数器,以便所有元素都知道计数器的存在并且可以继承或使用它的值。
body {counter-reset: h1}
h1 {counter-reset: h2}
h2 {counter-reset: h3}
h1:before {counter-increment: h1; content: counter(h1)". "}
h2:before {counter-increment: h2; content: counter(h1)"." counter(h2)". "}
h3:before {counter-increment: h3; content: counter(h1)"." counter(h2)"." counter(h3)". "}
<!-- body creates counter.h1, sets it to 0 -->
<div class="test"> <!-- Inherits counter.h1 from parent -->
<h1>Heading 1 <!-- Again inherits counter.h1 from parent, creates counter.h2 -->
<!-- ::before increments counter.h1 to 1 and display value-->
</h1>
</div>
<p>Paragraph</p>
<h2>Heading 2 <!-- Inherits counter.h1 as it is from parent but not counter.h2, creates counter.h3 -->
<!-- ::before has no counter.h2, so creates a counter.h2 and increments to 1 -->
</h2>
<p>Paragraph</p>
<h3>Heading 3 <!-- Inherits counter.h1 as it is from parent, couunter.h3 from sibling but not counter.h2 -->
<!-- ::before inherits counter.h3 from parent and increments to 1, has no counter.h2 so creates a new counter.h2 and sets to 0 -->
</h3>
<p>Paragraph</p>
<h3>2nd Heading 3 <!-- Inherits counter.h1 as it is from parent, couunter.h3 from sibling but not counter.h2 -->
<!-- ::before inherits counter.h3 from parent and increments to 2, has no counter.h2 so creates a new counter.h2 and sets to 0 -->
</h3>
<p>Paragraph</p>
<h2>2nd Heading 2 <!-- Inherits counter.h1 as it is from parent, couunter.h3 from sibling but not counter.h2, resets counter.h3 to 0 -->
<!-- ::before has no counter.h2, so creates a counter.h2 and increments to 1 -->
</h2>
<p>Paragraph</p>
<h2>3rd Heading 2 <!-- Inherits counter.h1 as it is from parent, couunter.h3 from sibling but not counter.h2, resets counter.h3 to 0 -->
<!-- ::before has no counter.h2, so creates a counter.h2 and increments to 1 -->
</h2>
<p>Paragraph</p>
<h1>2nd Heading 1 <!-- Inherits counter.h1 as it is from parent, couunter.h3 from sibling but not counter.h2, resets counter.h2 to 0 -->
<!-- ::before inherits counter.h1 from parent and increments to 2 -->
</h1>
答案 1 :(得分:5)
考虑一下(非常类似于你的结构,只是更简单一点):
body {
counter-reset: h1;
}
h1:before {
content: counter(h1) ". ";
counter-increment: h1;
}
h1 {
counter-reset: h2;
}
h2:before {
content: counter(h1) "." counter(h2) ". ";
counter-increment: h2;
}
&#13;
<div>
<h1>Heading first level 1</h1>
</div>
<h2>Heading second level 1</h2>
<h2>Heading second level 2</h2>
<h2>Heading second level 3</h2>
<h2>Heading second level 4</h2>
<h2>Heading second level 5</h2>
<h1>Heading first level 2</h1>
<h2>Test</h2>
<h2>Test</h2>
<h2>Test</h2>
<h1>Heading first level 3</h1>
<h1>Heading first level 4</h1>
&#13;
通过推荐:
计数器是&#34;自我嵌套&#34;,在重置计数器的意义上 后代元素或伪元素自动创建一个新元素 柜台的实例。这对于列表等情况很重要 在HTML中,元素可以嵌套在任意内容中 深度。
布局中的问题是<h1>
内的第一个<div>
初始化h1
计数器的单独实例。这是因为计数器对嵌套元素很敏感。每次重置一个不同级别的计数器时,这不会影响另一个级别的同一个计数器实例!
以下是发生的事情:
01. <body> | h1 = *
02. <div> |
03. <h1>Heading first level 1</h1> | h1 = 1 | div-h2 = *
04. </div> |
05. <h2>Heading second level 1</h2> | | h2 = 1
06. <h2>Heading second level 2</h2> | | h2 = 1
07. <h2>Heading second level 3</h2> | | h2 = 1
08. <h2>Heading second level 4</h2> | | h2 = 1
09. <h2>Heading second level 5</h2> | | h2 = 1
10. <h1>Heading first level 2</h1> | h1 = 2 | h2 = *
11. <h2>Test</h2> | | h2 = 1
12. <h2>Test</h2> | | h2 = 2
13. <h2>Test</h2> | | h2 = 3
14. <h1>Heading first level 3</h1> | h1 = 3
15. <h1>Heading first level 4</h1> | h1 = 4
正如您所见,在01.
我们重置了正常工作的h1
计数器。但是,在h1
元素中,我们会重置计数器h2
。
03.
问题出现在我们重置嵌套级别h2
中的计数器div
的情况下,为了澄清这一点,我称之为计数器:div-h2
。事实上,h2
到05.
的下一个09.
元素正在使用另一个尚未重置的计数器!这是计数器h2
(没有嵌套),即使他们试图递增它,也没有什么可以增加,因为重置是强制性的!
在10.
中,我们没有div
嵌套,因此计数器h2
被正确重置,因此也会增加。
在您的情况下,您必须避免生成页面中不同类的嵌套结构。这是一个干净的HTML建议,在你的情况下,如果你真的需要保留该div,只需在重置计数器div
的地方添加h2
选择器:
div {
counter-reset: h2;
}
所以这是最后的工作片段:
body {
counter-reset: h1;
}
h1:before {
content: counter(h1) ". ";
counter-increment: h1;
}
h1 {
counter-reset: h2;
}
div {
counter-reset: h2;
}
h2:before {
content: counter(h1) "." counter(h2) ". ";
counter-increment: h2;
}
&#13;
<div>
<h1>Heading first level 1</h1>
</div>
<h2>Heading second level 1</h2>
<h2>Heading second level 2</h2>
<h2>Heading second level 3</h2>
<h2>Heading second level 4</h2>
<h2>Heading second level 5</h2>
<h1>Heading first level 2</h1>
<h2>Test</h2>
<h2>Test</h2>
<h2>Test</h2>
<div>
<h1>Heading first level 1</h1>
</div>
<h2>Test</h2>
<h2>Test</h2>
<h2>Test</h2>
<h1>Heading first level 3</h1>
<h1>Heading first level 4</h1>
&#13;
如果您只为div
设置了h1
嵌套,以防您希望将其他标题元素包含在div
中,那么上面的解决方案就有效了,而不是需要重置h3
1}}也在那里反击!但我不推荐这个,因为它是一个非常混乱的CSS安排:难以维护,不易遵循。
请记住,在CSS中始终有一种实现目标的方法,你说你需要div
,但我认为你并没有尝试所有可能来摆脱它。