[CSS] counter-incrementで連番数値を表示する覚書

2023年2月10日

CSS Tips 学習

eyecatch ホームページでリストや順番の番号(連番)を表示するのに、ベタ書きしている人、いね〜よな〜。 cssのcounter機能を使って便利にできる上、ホームページメンテナンスやajax対応などでも効果が発揮できるので、これはもはや定番で使う機能と思っておいたほうが良い。 そして、いつもこの機能を設定する時に、ググって、コピって、ペーストするのがいい加減ウザくなってきたので、自分用に便利にコピペできる覚書をブログに残しておきます。

cssのcounter機能について

cssのカウンター機能を知らないという人の為に、説明をしてみたいと思います。

CSSカウンター機能とは?

olタグで連番が表示できる機能を、html内のリスト構造のいたるところで、連番表示出来るようにする機能。 次のようなテーブル構造の場合、先頭列のセルに連番を表示する事が可能になります。

サンプルコード

<table class='jobs'> <thead> <tr> <th class='num'>#</th> <th class='name'>名前</th> <th class='job'>職業</th> </tr> </thead> <tbody> <tr> <th class='num'></th> <td class='name'>ヨシヒコ</td> <td class='job'>勇者</td> </tr> <tr> <th class='num'></th> <td class='name'>メレブ</td> <td class='job'>魔法使い</td> </tr> <tr> <th class='num'></th> <td class='name'>ダンジョー</td> <td class='job'>剣士</td> </tr> <tr> <th class='num'></th> <td class='name'>ムラサキ</td> <td class='job'>父の仇</td> </tr> </tbody> </table> table.jobs .num{ width:50px; } table.jobs tbody{ counter-reset:num 0; } table.jobs tbody tr{ counter-increment: num; } table.jobs tbody tr .num::before{ content: counter(num); }

デモ

# 名前 職業
ヨシヒコ 勇者
メレブ 魔法使い
ダンジョー 剣士
ムラサキ 父の仇

解説

tbody > tr > th.num
  1. numという変数を使って連番をカウントアップ(increment)します
  2. 階層構造のroot部分に当たるtbodyに "counter-reset:num 0;" をセット
  3. 連番カウントする箇所に "counter-increment" をセット
  4. 数字を表示するエレメントの疑似要素(::beforeまたは::after)のcontentに "counter(num)" をセット

ポイント

  • numという変数名は、複数セットできる。
  • counter-resetの開始数値は最初にインクリメントされるため、1から始まる場合は0にする、0から始まる場合は、-1にする。
  • counter-resetの数値は書かなくてもOK(デフォルトは0)

ゼロパディングする方法

counter(変数名 , decimal-leading-zero) counter()に"decimal-leading-zero"オプションをセットすると、 「1,2,3,4」 -> 「01,02,03,04」 のようにゼロパディングされる。 桁数合わせが必要な場合に使用できます。

アラビア数字じゃなくローマ数字で表示する方法

counter(変数名 , upper-roman) counter()に"upper-roman"オプションをセットすると、 「1,2,3,4」 -> 「I,II,III,IV」 のようにローマ数字で表示することができる。

階層で連番表示したい場合

契約書の付番や、書籍の見出しリストなどでよく見る、階層連番記述がセットできます。 <h2>買い物リスト</h2> <ol class='level'> <li> くだもの <ol> <li>リンゴ</li> <li>バナナ</li> <li>みかん</li> </ol> </li> <li>肉</li> <li>魚</li> <li> おかし <ol> <li>チョコ系</li> <li> スナック系 <ol> <li>ポテチ</li> <li>ポップコーン</li> <li>とんがりコーン</li> </ol> </li> </ol> </li> </ol> ol.level { counter-reset: listCounter; } ol.level li { counter-increment: listCounter; } ol.level li::marker { content: counters(listCounter, '.', upper-roman) ': '; } ol.level li::before { content: counters(listCounter, ".") "." counters(listCounter, ".") ; }

デモ

買い物リスト
  1. くだもの
    1. リンゴ
    2. バナナ
    3. みかん
  2. おかし
    1. チョコ系
    2. スナック系
      1. ポテチ
      2. ポップコーン
      3. とんがりコーン

あとがき

cssを使って表示管理がめちゃくちゃ便利になっていきますね。 単なる連番だけじゃなく、階層連番などもコントロールできるようになると、色々な仕事で使う文章なんかも、htmlで書きたくなってきちゃいます。 マークダウンも、こういうcssの機能に合わせてアップグレードされて欲しいなあ。