【CSS】ゼロ埋めも階層化もCSSだけで!counter でリストに自動で番号(連番)を振る方法
Webサイトで「1. 2. 3.」といった番号付きリストを作る時、<ol> タグのデフォルトスタイルではデザインの自由度が低く、困ったことはありませんか?
そんな時に活躍するのが、CSSの counter-reset と counter-increment を使った「CSSカウンター」という機能です! これを使えば、HTML側に直接数字を書かなくても、CSSの擬似要素(::before)を使って自由に連番を生成・デザインすることができます。
今回は、基本の使い方から、よく使う「01, 02のようなゼロ埋め」「Step 1などの文字追加」「1-1, 1-2などの階層化」まで、コピペで使えるデモをまとめました!
デモ動作
See the Pen CSSカウンターで作る!自動連番リスト by mikanbako (@mikanbako) on CodePen.
demo: CSSカウンターで作る!自動連番リスト
実装コード紹介
【HTML】
<div class="l-wrap">
<h2>CSSカウンター 活用デモ</h2>
<div class="p-demo-box">
<!-- 💡 1. ゼロ埋め(01, 02...) -->
<section class="p-section">
<h3>1. ゼロ埋めスタイル(01, 02...)</h3>
<ul class="c-list-zero">
<li class="c-list-zero__item">要件定義・デザイン作成</li>
<li class="c-list-zero__item">HTML/CSS/JSコーディング</li>
<li class="c-list-zero__item">テスト・公開</li>
</ul>
</section>
<!-- 💡 2. テキスト付き(Step 1, Step 2...) -->
<section class="p-section">
<h3>2. カスタムテキスト付き(Step 1, Step 2...)</h3>
<ul class="c-list-step">
<li class="c-list-step__item">お問い合わせ</li>
<li class="c-list-step__item">お見積もりのご提示</li>
<li class="c-list-step__item">ご契約・制作開始</li>
</ul>
</section>
<!-- 💡 3. 階層化(1-1, 1-2...) -->
<section class="p-section">
<h3>3. 階層化(ネスト)スタイル(1-1, 1-2...)</h3>
<ol class="c-list-nested">
<li class="c-list-nested__item">はじめに
<ol class="c-list-nested">
<li class="c-list-nested__item">ご挨拶</li>
<li class="c-list-nested__item">本記事の目的
<ol class="c-list-nested">
<li class="c-list-nested__item">サンプル</li>
<li class="c-list-nested__item">Sample</li>
</ol>
</li>
</ol>
</li>
<li class="c-list-nested__item">メインコンテンツ
<ol class="c-list-nested">
<li class="c-list-nested__item">サンプル</li>
<li class="c-list-nested__item">Sample</li>
</ol>
</li>
</ol>
</section>
</div>
</div>
【CSS】
/* ベース装飾 */
.l-wrap {
padding: 40px 20px;
max-width: 700px;
margin: 0 auto;
line-height: 1.6;
color: #3e3e3e;
}
h2 {
margin-bottom: 30px;
font-size: 16px;
color: #1bb4d4;
text-align: center;
}
.p-demo-box {
display: flex;
flex-direction: column;
gap: 40px;
}
.p-section {
padding: 30px;
background: #fff;
border-radius: 12px;
box-shadow: 0 4px 15px rgb(0 0 0 / 5%);
}
h3 {
padding-bottom: 10px;
margin-bottom: 20px;
font-size: 18px;
font-weight: bold;
border-bottom: 2px solid #eee;
}
/* =========================================
💡 1. ゼロ埋めスタイル
========================================= */
.c-list-zero {
list-style: none; /* デフォルトの点を消す */
/* 親要素でカウンターを初期化(名前は任意でOK) */
counter-reset: zero-counter;
}
.c-list-zero__item {
position: relative;
padding-left: 40px;
margin-bottom: 15px;
font-size: 16px;
/* 各li要素でカウンターを1ずつ増やす */
counter-increment: zero-counter;
}
.c-list-zero__item::before {
position: absolute;
top: 0;
left: 0;
font-size: 18px;
font-weight: bold;
color: #1bb4d4;
/* decimal-leading-zero を指定してゼロ埋め! */
content: counter(zero-counter, decimal-leading-zero);
}
/* =========================================
💡 2. カスタムテキスト付き(Step 1など)
========================================= */
.c-list-step {
list-style: none;
counter-reset: step-counter; /* カウンター初期化 */
}
.c-list-step__item {
position: relative;
padding-left: 70px; /* Stepの文字が入る分、余白を広めに */
margin-bottom: 15px;
font-size: 16px;
counter-increment: step-counter; /* カウンター増加 */
}
.c-list-step__item::before {
position: absolute;
top: 0;
left: 0;
padding: 2px 8px;
font-size: 14px;
font-weight: bold;
color: #fff;
/* 文字列とカウンターを組み合わせる! */
content: "Step " counter(step-counter);
background: #e83e8c;
border-radius: 4px;
}
/* =========================================
💡 3. 階層化(ネスト)スタイル
========================================= */
.c-list-nested {
padding-left: 20px; /* 階層ごとのインデント */
list-style: none;
counter-reset: nested-counter; /* カウンター初期化 */
}
.c-list-nested__item {
position: relative;
margin-bottom: 8px;
font-size: 16px;
counter-increment: nested-counter; /* カウンター増加 */
}
.c-list-nested__item::before {
margin-right: 8px;
font-size: 16px;
font-weight: bold;
color: #28a745;
/* counters関数を使うと、親の番号を引き継いで区切り文字を指定できる! */
content: counters(nested-counter, "-");
}
コードの解説・仕組み
CSSカウンターの基本ルール
CSSカウンターを機能させるには、以下の3つのステップが必須です。これさえ覚えておけば迷いません!
counter-reset: 名前;
親要素(ulやol)に指定して、カウンターを「0」にリセットします。counter-increment: 名前;
子要素(li)に指定して、カウンターを「1」ずつ増やします。content: counter(名前);
子要素の擬似要素(::before)に指定して、画面に数字を出力します。
/* =========================================
💡 基本ステップ
========================================= */
ul,
ol {
...
counter-reset: test-counter; /* カウンター初期化 */
}
li {
...
counter-increment: test-counter; /* カウンター増加 */
}
li::before {
...
/* カウンターを出力 */
content: counter(test-counter);
}
便利な応用テクニック
ゼロ埋めcontent: counter(名前, decimal-leading-zero); と第2引数を指定するだけで、01, 02… と自動でゼロ埋めしてくれます。
/* =========================================
💡 1. ゼロ埋めスタイル
========================================= */
.c-list-zero__item::before {
...
/* decimal-leading-zero を指定してゼロ埋め! */
content: counter(zero-counter, decimal-leading-zero);
}
階層化
親の番号を引き継いで「1-1」「1-2」のようにしたい時は、counter() ではなく複数形の counters(名前, "区切り文字") を使うと実装できます!
/* =========================================
💡 3. 階層化(ネスト)スタイル
========================================= */
.c-list-nested__item::before {
...
/* counters関数を使うと、親の番号を引き継いで区切り文字を指定できる! */
content: counters(nested-counter, "-");
}
補足:公式ドキュメント
まとめ
今回はCSSの counter-reset を使った、リストの自動採番テクニックをご紹介しました。
手動でHTMLに数字を書き込んでしまうと、後から項目が追加・削除された時にすべての数字を修正しなければならず、保守性が非常に悪くなってしまいます。
CSSカウンターを使えば、ブラウザが自動で番号を計算してくれるため、メンテナンスしやすいコードを書くことができます。ぜひこのテクニックをマスターしてご自身のWeb制作に利用してみてください!