cssでlistのナンバリングはカスタマイズできる!

前口上

太郎くんはNPO団体のWEBサイトを作成しています。
定款に長い長い原稿を貰いました。ただの数字ではなく「第○章」や「(○)」のリストだったので、list-style:none;で通常のナンバリングを消しテキストの形で全て流し込みました。
後日修正指示が入り、一項目削除されたり追加されたりしました。修正箇所は一箇所でも、連なる他の番号もそれに合わせて変更しなければなりません。
地味だけどミスが発生しやすい嫌〜な作業です。
太郎くんが余計にかけてしまった工数は何hでしょう?

counter-incrementとcontent:counter();を使えば、もっとスマートにできる!

脱アナログ作業を目指しましょう。

counter-incrementプロパティの説明

increment インクリメントとは「増加させる」という意味です。

ol {
 list-style: none; 
}
ol li {
 counter-increment: 任意の名前; 
}

基本的にol liに使用することになると思いますが、見出しなどにも使えちゃいます。

content:counter();の説明

擬似要素に必ず出てくるので、ちゃんと説明できないけど使用頻度は高いcontentプロパティ。
私が普段使うのはほぼほぼcontent:'';ですが、今回はcontent:counter();として自動連番させて使用します。

liの擬似要素のcontentでさきほど付けた任意の名前を呼び出します。

ol li:before {
 content: "("counter(任意の名前)") "; 
}

シンプルに実装してみる

今回、counter-incrementに付加する名前をcount-ex01でテストしてみます。
また管理のため、olにcount-ex01というclassを付加しています(同じ名前である必要はありませんが、自分的に分かりやすいので同じ名前を使用しています。人によっては余計ややこしいかも)。

<ol class="count-ex01">
  <li>ダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキスト</li>
  <li>ダミーテキスト</li>
  <li>ダミーテキスト</li>
  <li>ダミーテキスト</li>
  <li>ダミーテキスト</li>
  <li>ダミーテキスト</li>
  <li>ダミーテキスト</li>
  <li>ダミーテキスト</li>
  <li>ダミーテキスト</li>
  <li>ダミーテキスト</li>
</ol>
ol.count-ex01 > li {
 counter-increment: count-ex01; 
 position: relative;
 padding-left: 3.5rem;
}
ol.count-ex01 > li:before {
 content:  "第" counter(count-ex01) "章";
 position: absolute;
 top: 0;
 left: 0;
}

content: "("counter(count-ex01)") ";だとただのナンバリングになってしまって普通のolと変わらないので、「第○章」でリストになるようにします。
「ダ」の字の頭を揃えたいので、lipadding-left: 3.5rem;を設定し、擬似要素はposition:absolute; top:0; left:0;を使って左上に配置し、改行してもインデントが効くようになりました。

DEMO
  1. ダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキスト
  2. ダミーテキスト
  3. ダミーテキスト
  4. ダミーテキスト
  5. ダミーテキスト
  6. ダミーテキスト
  7. ダミーテキスト
  8. ダミーテキスト
  9. ダミーテキスト
  10. ダミーテキスト

アレンジ

リストの数が9以内のとき限定ですが、「01」「02」・・・と頭に0が付くようにしてみます。

普通にlist-style-type: decimal-leading-zero;を使えば、「01」「02」・・・「10」「11」となります。が、この記事ではcontent:counter();を使いたいので、強情に進めます。

counter-incrementに付加する名前をcount-ex01-2にして、前の例のcontent: "第" counter(count-ex01) "章";content: "0"counter(count-ex01-2);にします。

頭の文字だけ変えた例を上げても代わり映えしないので、CSSでデザインを調整してみました。

<ol class="count-ex01-2">
  <li>ダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキスト</li>
  <li>ダミーテキスト</li>
  <li>ダミーテキスト</li>
  <li>ダミーテキスト</li>
  <li>ダミーテキスト</li>
  <li>ダミーテキスト</li>
  <li>ダミーテキスト</li>
</ol>
ol.count-ex01-2 {
  list-style: none;
  padding-left: 0;
}
ol.count-ex01-2 > li {
  counter-increment: count-ex01-2;
  position: relative;
  padding: 20px 30px 20px 85px;
  background: #ccc;
  font-size: 14px;
  margin-bottom: 10px;
}
ol.count-ex01-2 > li:before {
  position: absolute;
  content:  "0"counter(count-ex01-2);
  display: inline-block;
  background: #666;
  border-radius: 50%;
  font-family: 'Roboto', sans-serif;
  font-weight: 700;
  font-size: 22px;
  color: white;
  left: 20px;
  width: 50px;
  height: 50px;
  line-height: 50px;
  text-align: center;
  top: 50%;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}

上記CSSはあくまで例ということで。。

DEMO
  1. ダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキストダミーテキスト
  2. ダミーテキスト
  3. ダミーテキスト
  4. ダミーテキスト
  5. ダミーテキスト
  6. ダミーテキスト
  7. ダミーテキスト

olの数字の部分をFontを変えたい、色を変えたいなどの場合も、上記のようにollist-style: none;にしてから、libefore要素で数字を記述しstyleを当てるようにします。

この調子で入れ子のlistも作ってみる

入れ子にするlistも作ってみます。
入れ子にするol licounter-incrementに付加する名前をcount-ex02でテストしてみます。olにもcount-ex02とclassを付加しています。

Bootstrapのデフォルトでolやulにpadding-left: 40px;が付いていて邪魔なので、padding-left: 0;を当て直しています。

<ol class="count-ex01">
  <li>ダミーテキスト
    <ol class="count-ex02">
      <li>入れ子のリスト</li>
      <li>入れ子のリスト</li>
    </ol>
  </li>
  <li>ダミーテキスト
    <ol class="count-ex02">
      <li>入れ子のリスト</li>
      <li>入れ子のリスト</li>
    </ol>
  </li>
  <li>ダミーテキスト</li>
</ol>
ol.count-ex02 {
  list-style: none;
  padding-left: 0;
}
ol.count-ex02 > li {
  counter-increment: count-ex02;
  position: relative;
  padding-left: 3rem;
}
ol.count-ex02 > li:before {
  content:  "(" counter(count-ex02) ")";
  position: absolute;
  top: 0;
  left: 0;
}
Demo
  1.  ダミーテキスト
    1. 入れ子のリスト
    2. 入れ子のリスト
  2. ダミーテキスト
    1. 入れ子のリスト
    2. 入れ子のリスト
  3. ダミーテキスト

アルファベットやローマ数字の連番もできる

普通のやり方

まず、おさらいで普通にol type=""でアルファベットやローマ数字の連番にする方法です。

ol type=”1″ 数字(デフォルト) 1, 2, 3, 4, 5…
ol type=”a” アルファベットの小文字 a, b, c, d, e…
ol type=”A” アルファベットの大文字 A, B, C, D, E…
ol type=”i” ローマ数字の小文字 i, ii, iii, iv, v…
ol type=”I” ローマ数字の大文字 I, II, III, IV, V…
<ol class="count-ex01">
  <li>ダミーテキスト
    <ol class="count-ex02">
      <li>入れ子のリスト</li>
    </ol>
  </li>
  <li>ダミーテキスト
    <ol class="count-ex02">
      <li>入れ子のリスト</li>
      <li>入れ子のリスト
        <ol type="i">
          <li>入れ入れ子は普通のやり方でローマ数字</li>
          <li>入れ入れ子は普通のやり方でローマ数字</li>
          <li>入れ入れ子は普通のやり方でローマ数字</li>
          <li>入れ入れ子は普通のやり方でローマ数字</li>
          <li>入れ入れ子は普通のやり方でローマ数字</li>
        </ol>
      </li>
    </ol>
  </li>
</ol>
DEMO
  1. ダミーテキスト
    1. 入れ子のリスト
  2. ダミーテキスト
    1. 入れ子のリスト
    2. 入れ子のリスト
      1. 入れ入れ子は普通のやり方でローマ数字
      2. 入れ入れ子は普通のやり方でローマ数字
      3. 入れ入れ子は普通のやり方でローマ数字
      4. 入れ入れ子は普通のやり方でローマ数字
      5. 入れ入れ子は普通のやり方でローマ数字

content:counter();に指定するやり方

任意の名前を付けるカッコ内に追記します。

content:counter(任意の名前, hiragana); 平仮名 あ, い, う, え, お…
content:counter(任意の名前, katakana); 片仮名 ア, イ, ウ, エ, オ…
content:counter(任意の名前, hiragana-iroha); 平仮名いろは い, ろ, は, に, ほ…
content:counter(任意の名前, katakana-iroha); 片仮名イロハ イ, ロ, ハ, ニ, ホ…
content:counter(任意の名前, lower-alpha); アルファベットの小文字 a, b, c, d, e…
content:counter(任意の名前, upper-alpha); アルファベットの大文字 A, B, C, D, E…
content:counter(任意の名前, lower-roman); ローマ数字の小文字 i, ii, iii, iv, v…
content:counter(任意の名前, upper-roman); ローマ数字の大文字 I, II, III, IV, V…

バリエーションが増えてますね。

ローマ数字の小文字で入れ子にするol licounter-incrementに付加する名前をcount-ex03
平仮名のいろはで入れ子にするol licounter-incrementに付加する名前をcount-ex04
でテストしてみます。olにもそれぞれcount-ex03count-ex04とclassを付加しています。

<ol class="count-ex01">
  <li>ダミーテキスト
    <ol class="count-ex02">
      <li>入れ子のリスト
        <ol class="count-ex03">
          <li>入れ入れ子ダミーテキスト</li>
          <li>入れ入れ子ダミーテキスト</li>
        </ol>
      </li>
    </ol>
  </li>
  <li>ダミーテキスト
    <ol class="count-ex02">
      <li>入れ子のリスト</li>
      <li>入れ子のリスト
        <ol class="count-ex04">
          <li>入れ入れ子ダミーテキスト</li>
          <li>入れ入れ子ダミーテキスト</li>
        </ol>
      </li>
    </ol>
  </li>
</ol>
ol.count-ex03 {
  list-style: none;
  padding-left: 0;
}
ol.count-ex03 > li {
  counter-increment: count-ex03;
  position: relative;
  padding-left: 9rem;
}
ol.count-ex03 > li:before {
  content: "Secondary Item-" counter(count-ex03, lower-roman) "." ;
  position: absolute;
  top: 0;
  left: 0;
}
ol.count-ex04 {
  list-style: none;
  padding-left: 0;
}
ol.count-ex04 > li {
  counter-increment: count-ex04;
  position: relative;
  padding-left: 4rem;
}
ol.count-ex04 > li:before {
  content: "条例 " counter(count-ex04, hiragana-iroha) ;
  position: absolute;
  top: 0;
  left: 0;
}
DEMO
  1. ダミーテキスト
    1. 入れ子のリスト
      1. 入れ入れ子ダミーテキスト
      2. 入れ入れ子ダミーテキスト
  2. ダミーテキスト
    1. 入れ子のリスト
    2. 入れ子のリスト
      1. 入れ入れ子ダミーテキスト
      2. 入れ入れ子ダミーテキスト

後書き

今回はlistで実装テストをしましたが、見出し等にも使用できます。

リセットはcounter-resetを使う

また、連番させたくないlistにまで数字がカウントされていく場合に、区切りとなる要素にcounter-reset: 任意の名前;を指定してリセットをします。
今回は使ってませんが、実際に使用する際には必要であろう情報なのでメモっておきます。