【CSS】counterを使用してオリジナルの目次を作ろう!

CSSのcounterを使用して、自動連番される目次を作成していく流れと使用する機能を解説していきます。
今回紹介するCSSのcounterを使用すれば簡単に自動で連番を振り分けることができます。
この機能を使って、目次を作成してみましょう。
この記事を読んだらできるようになること
- CSSのcounterを使いこなせるようになる
- 疑似要素の基本がわかるようになる
- 自分で目次を作成できるようになる
作成する目次のゴール
以下の要件を満たす目次を作っていきます。
- メイン、サブ階層を持つ
- 階層数に上限はない(サブ階層の更に下の階層がある)
- メイン階層の連番は「(番号). 」の形式とする
- 連番は「(メイン階層).(サブ階層).(さらに下の階層)・・・」の形式とする
例:
1 2 3 4 5 6 |
1. TOPIC 1 1.1 TOPIC 1-1 1.2 TOPIC 1-2 1.3 TOPIC 1-3 2. TOPIC 2 3. TOPIC 3 |
ol要素のみで作成する
まずはol要素を使って、目次を作ってみます。
ソース
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<html> <head> </head> <body> <ol> <li> TOPIC 1 <ol> <li>TOPIC 1-1</li> <li>TOPIC 1-2</li> <li>TOPIC 1-3</li> </ol> </li> <li>TOPIC 2</li> <li>TOPIC 3</li> </ol> </body> </html> |
メイン階層が3つあり、TOPIC1の下に更にサブ要素がある目次になるはずです。
それでは、このソースの結果を見てみましょう。
実行結果
メイン階層には連番が付き、要件を満たすことができました。
しかしサブ階層にはメイン階層の番号がなく、階層関係がわかりにくい目次ができてしまいました。
よってol要素による目次の作成には以下の欠点があることがわかります。
- ol要素は連番を付加することができるが、階層を認識しない
counterを使用して作成する
今度はol要素に加えて、counterを使用して目次を作成してみます。
ソース
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<html> <head> <style> ol { counter-reset: section; list-style: none; } li::before { counter-increment: section; content: counters(section,".") ". "; } </style> </head> <body> <ol> <li> TOPIC 1 <ol> <li>TOPIC 1-1</li> <li>TOPIC 1-2</li> <li>TOPIC 1-3</li> </ol> </li> <li>TOPIC 2</li> <li>TOPIC 3</li> </ol> </body> </html> |
3-12行の<style>タグ内を追加しました。ここで登場するのがcounterです。
これら機能を使用すると自動で連番する処理を実装できます。
counter-reset
様々なプログラミング言語で変数の初期化を行うのと同様に、この記述で連番に使用する変数を宣言し、初期化します。
以下のように記述されます。
1 |
counter-reset: <変数名> |
上記で定義された<変数名>を使用して、連番を付加していきます。
また、以下は重要な仕様です。
- counter-resetで定義される変数名は階層ごとにスコープが異なる
counter-increment
counter-resetで初期化された変数を加算する処理を実施します。
以下のように記述されます。
1 |
counter-increment: <変数名> |
counterで変数を宣言、加算させることができますが、これだけではまだ表示できません。
counter-resetで宣言された変数は、疑似要素のcontent内で使用することができます。
疑似要素とは?確認してみましょう。
疑似要素
CSS の 疑似要素はセレクターに付加するキーワードで、選択された要素の特定の部分にスタイル付けできるようにするものです。
例えば
::first-line
疑似要素は、段落の最初の行のフォントを変更するために使用することができます。
つまり画面上に表示できる要素をCSSで定義することができます。
この疑似要素では様々な位置を指定できますが、目次作成で使用するのは::beforeです。
1 2 3 4 |
<先頭に疑似要素を付加したい要素のセレクタ>::before { content: <表示する内容(文字列など)> /*以下疑似要素のスタイル*/ } |
::beforeとcounter-incrementを組み合わせることにより、目次の先頭要素に文字列を付加することができます。
1 2 3 4 |
li::before { counter-increment: section; /*li要素が表示される度にsectionを加算*/ content: counters(section,".") ". "; /*加算された内容を表示する*/ } |
counter-resetで宣言された変数は疑似要素のcontent内で使用することができるので、これで連番が表示されるようになります。
ただ最後にまた新しい機能が出てきました。countersです。
counters
counter-resetで宣言された変数を、疑似要素のcontent内で表示するための機能です。
以下のように記述されます。
1 |
counters(<変数名>, <区切り文字>) |
同じ<変数名>が異なる階層で定義されていた場合、上階層から順番に区切り文字を付加して表示できます。
<上階層><区切り文字><下階層><区切り文字><さらに下階層>・・・
counter-resetの説明内で「counter-resetで定義される変数名は階層ごとにスコープが異なる」と解説しました。
この仕様により、countersと組み合わせることでどんなに下の階層が増えても変数名が1つで済みます
まさに目次の作成のため生まれた機能です。