普通のHTMLの書き方では目次にol
要素を使っ(てしまっ)たが、対応する見出しには番号がない。これはあまり良くなさそうだが、文字列として追加するのも何だな……とCSSでやろうとしていた。ひとつのカウンターを作って、counters()
による連結だけでいけるかと考えたが、うまくいかなかった。
セクションのレベルごとにcouter()
を作る、というのが結論だ。counters()
はこのケースでは利用できない、というよりもほぼリスト系のためだけに存在することがわかった。
counters()
の利用対象のHTML文書では、section
とh1
要素のみというストイックな記述になっている。そのためsection
要素でリセットして、h1
要素でインクリメントすれば良いだろうと、まずは以下のように書いた。
section {
counter-reset: section;
}
section h1::before {
content: counters(section, ".") ". ";
counter-increment: section;
}
これだとすべての見出しに「1.」や「1.1.」が付く。当たり前だがsection
要素ごとにリセットされるからだ。このパターンはol
とli
要素のような構造ではうまく振られる。
counter-reset
の工夫数字をリセットするタイミングが悪い、と勘違いした。そのため次はそれを制御しようと以下のように書いた。
main,
main > section {
counter-reset: section;
}
section h1::before {
content: counters(section, ".") ". ";
counter-increment: section;
}
これだとカウンターとその利用がうまくマッピングされない。そのため「0.1」や「0.3」などセクションのネストを無視した連番になってしまう。
落ち着いて考えるとcounters()
で連番を振れるのはネストしあう要素同士だけで、それに含まれる要素へは無理だった。最後にたどり着いたのはカウンターを大見出しと小見出しでわける方法だ。
main {
counter-reset: section;
}
main > section {
counter-reset: subsection;
}
main > section > h1::before {
content: counter(section) ". ";
counter-increment: section;
}
main > section > section > h1::before {
content: counter(section) "." counter(subsection) ". ";
counter-increment: subsection;
}
section
要素がある分、h1
やh2
要素でフラットな構造を持つ場合と違って複雑になるが、これでうまく振れる。
結局は採用を見送ったので、もはやどうでも良い話だ。頭の体操と仕様を見直すきっかけにはなった。
CSSのカウンターは、CSS2時代から存在するが、Internet Explorer 6などで実装されなかったので日の目を見なかった。ChromeやFirefoxでのサポートで一瞬脚光を浴びたが、同時に使いどころがあまりないことも判明してしまい、そのまま忘れ去られたのだろう。