この動作の理由は、カウンターの作成、そのスコープ、および継承についてW3Cの仕様で述べられていることを確認することで、詳細に説明できます。
カウンター リセット: カウンターリセット プロパティは、要素に新しいカウンターを作成します。
カウンターの範囲: カウンターの範囲は、そのカウンターの「カウンター リセット」を持つドキュメント内の最初の要素から始まります。
カウンターの継承:カウンターとその値は、おそらく異なる要素から別々に継承されます。要素に以前の兄弟がある場合、兄弟のすべてのカウンターを継承する必要があります。それ以外の場合、要素に親がある場合は、親のすべてのカウンターを継承する必要があります。それ以外の場合、要素にはカウンターの空のセットが必要です。次に、要素はドキュメント順で直前の要素からカウンタ値を継承します。
div のないスニペットが機能するのはなぜですか?
作業スニペット ( のないものdiv
) では、次のことが起こります。
counter.h1
(要素と区別するためにプレフィックスを追加) で作成 (またはリセット) されbody
、その初期値は 0 に設定されます。
- すべての要素は親のカウンターを継承するため、内のすべての要素は を
body
取得しcounter.h1
ます。最初の要素が検出されるh1
と、値がcounter.h1
1 に増分されます。次h1
の要素が検出されると、前の要素からカウンタ値が継承され、2 に増分されます。
counter.h2
要素でカウンタが作成されh1
、値が 0 に設定されます。この値は の兄弟に表示され、h1
すべて継承できます。
- このスニペットでは、すべての
h2
要素が実際にはh1
要素の兄弟であるため、各要素は で既に作成されたものをh2
継承し、その値をインクリメントするだけです。そのため、最初に遭遇すると 1 になります。counter.h2
h1
h2
counter.h2
- 要素と同様に
h2
、要素もとh3
の両方の要素の兄弟であるため、 と も継承します。これが、このサンプルで番号付けが正しいままである理由です。h1
h2
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>
div を含むスニペットが機能しないのはなぜですか?
ここで、機能しないスニペット (h1
内に が存在するものdiv
) に行きましょう。
- ここでは、 が
h1
作成しますcounter.h2
が、これは の兄弟 (存在しない) によってのみ継承されh1
ます。
- 要素が検出されるたび
h2
に、UA はセレクターcounter.h2
内の値をインクリメントしようとします。:before
しかし、ここではh2
親は継承しないため、どちらも継承counter.h2
しh2:before
ません。このためh2:before
、独自のものが作成counter.h2
され、1 にインクリメントされます。
- カウンターは(の子である) によって作成されるため、後続
h2
の要素も継承できません。このため、 が検出されるたびに、その中に新しいカウンターが作成され、インクリメントされます。これが、すべてが1.1として表示される理由です。counter.h2
h2:before
h2
h2
:before
h2
- 同様に、どの
h3
要素も認識counter.h2
しておらず、インクリメントもしません。これが、それらが1.0.xとして表示される理由です。
- ただし、すべての要素の兄弟である要素
counter.h3
によって作成されたため、すべて継承できます。これが、適切にインクリメントされる理由です。h2
h3
counter.h3
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>
解決策は何ですか?
この問題の理想的な解決策は、すべての要素がカウンターの存在を認識し、その値を継承または使用できるように、本体自体で最初に 3 つのカウンターすべてをリセットすることです。
body {counter-reset: h1 h2 h3}
h1 {counter-reset: h2 h3}
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, counter.h2, counter.h3 sets all 0 -->
<div class="test"> <!-- Inherits all 3 counters -->
<h1>Heading 1 <!-- Inherits all 3 counters, resets counter.h2 and counter.h3 to 0 -->
<!-- ::before also inherits all 3 counters, increments counter.h1 to 1 and displays value -->
</h1>
</div>
<p>Paragraph</p>
<h2>Heading 2 <!-- Inherits all 3 counters, resets counter.h3 to 0 -->
<!-- ::before also inherits all 3 counters, increments counter.h2 to 1 and displays value -->
</h2>
<p>Paragraph</p>
<h3>Heading 3 <!-- Inherits all 3 counters -->
<!-- ::before also inherits all 3 counters, increments counter.h3 to 1 and displays value -->
</h3>
<p>Paragraph</p>
<h3>2nd Heading 3 <!-- Inherits all 3 counters -->
<!-- ::before also inherits all 3 counters, increments counter.h3 to 2 and displays value -->
</h3>
<p>Paragraph</p>
<h2>2nd Heading 2 <!-- Inherits all 3 counters, resets counter.h3 to 0 -->
<!-- ::before also inherits all 3 counters, increments counter.h2 to 2, resets counter.h3 to 0 and displays value -->
</h2>
<p>Paragraph</p>
<h2>3rd Heading 2 <!-- Inherits all 3 counters, resets counter.h3 to 0 -->
<!-- ::before also inherits all 3 counters, increments counter.h2 to 3, resets counter.h3 to 0 and displays value -->
</h2>
<p>Paragraph</p>
<h1>2nd Heading 1 <!-- Inherits all 3 counters, resets counter.h2 and counter.h3 to 0 -->
<!-- ::before also inherits all 3 counters, increments counter.h1 to 2, resets counter.h2, counter.h3 to 0 and displays value -->
</h1>