リストデザインの「その先」へ:`list-style-type`の極意と`@counter-style`による完全制御
フロントエンドの実務において、リスト要素(`ul`, `ol`, `dl`)は避けては通れない「情報の骨格」です。しかし、デザインカンプに忠実なUIを実装しようとした瞬間、標準の`list-style-type`の制約に直面し、思わず`list-style: none`で消し去って、`::before`でアイコンを自作する――そんな経験、誰もが一度はあるはずです。
確かに`::before`による実装は強力ですが、リストのセマンティクスを損なわず、かつメンテナンス性を担保するためには、ブラウザ標準の仕様を正しく理解し、使いこなすことが重要です。今回は、中級エンジニアが知っておくべき`list-style-type`の深淵と、現代的なカスタムマーカーの解法を紐解いていきましょう。
—
1. `list-style-type`の現在地:標準値の再確認
まず基本ですが、`list-style-type`はリスト項目のマーカーを制御するプロパティです。多くのエンジニアが`disc`, `decimal`, `none`あたりを多用しますが、実はこれ以外にも強力なプリセットが存在します。
- 基本的なマーカー: `disc` (黒丸), `circle` (白丸), `square` (四角)
- 順序付きリスト: `decimal` (1, 2, 3…), `decimal-leading-zero` (01, 02, 03…), `lower-alpha` (a, b, c…), `katakana`, `hiragana` など
特に実務で意外と見落とされがちなのが、`decimal-leading-zero`のような「気の利いた」値です。わざわざJavaScriptで数値を加工しなくても、CSSだけで「01, 02…」といった洗練されたナンバリングが可能です。
—
2. ブラウザが裏側で行っていること
なぜ`list-style-type`を触るだけでマーカーが変わるのか。ブラウザは内部的に、リストアイテム(`display: list-item`)に対して、擬似的なマーカーボックス(`::marker`)を生成しています。
重要なのは、`::marker`擬似要素は、特定のCSSプロパティ(`content`, `color`, `font-size`など一部の限定的なもの)しか受け付けないという点です。つまり、複雑なレイアウトや背景画像を含んだマーカーを実現しようとすると、`::marker`だけでは力不足を感じる場面が出てきます。そこで登場するのが、CSSの次世代機能である`@counter-style`です。
—
3. @counter-styleで「唯一無二」のマーカーを作る
現場レベルで最も重宝するのが、`@counter-style`です。これを使えば、標準の記号に縛られず、プロジェクトのトーン&マナーに合わせた独自のナンバリングシステムを定義できます。
例えば、「ステップ表示」でよくある「STEP 01」のような形式を、リスト全体に適用してみましょう。
/ 独自のカウンターを定義 /
@counter-style step-counter {
system: numeric; / 数値ベースのシステムを指定 /
symbols: “0” “1” “2” “3” “4” “5” “6” “7” “8” “9”; / 数値のシンボル /
prefix: “STEP “; / 数字の前に置く文字列 /
suffix: ” : “; / 数字の後ろに置く文字列 /
}
.step-list {
list-style: none; / 標準のマーカーをオフ /
}
.step-list li {
/ 定義したカウンターを適用 /
list-style-type: step-counter;
/ 念のためインデントを調整 /
padding-left: 10px;
}
この方法の優れている点は、「HTML側がただの`ol`であること」です。JSで無理やりDOMを生成したり、CSSの`counter-increment`を手動で書く必要がありません。セマンティクスを維持したまま、デザイン要件をスマートに解決できます。
—
4. 実戦Tips:デザインを崩さないための注意点
最後に、現場でよく遭遇する「マーカーがズレる」「要素に被る」といったトラブルを防ぐためのベストプラクティスを共有します。
ul.custom-list {
/ マーカーをリストボックスの内側に配置し、レイアウト崩れを防ぐ /
list-style-position: inside;
/ 標準のマーカーを無効化し、::markerを制御する準備 /
list-style-type: none;
}
ul.custom-list li::marker {
/ ::markerは直接スタイルを当てられる /
content: “★ “;
color: #ffcc00;
font-weight: bold;
}
シニアからのアドバイス:
`list-style-position: inside` を使うと、リストが長文になった際にテキストがマーカーの下に回り込んでしまいます。デザイン的に許容できない場合は、`position: inside`を避け、`::before`で絶対配置にするか、`padding`で領域を確保する手法へ切り替えてください。
まとめ:技術は「使いどころ」で差がつく
`list-style-type`は一見地味なプロパティですが、その背後にはCSSの強力なカウンター制御機能が隠されています。
1. まずは標準の値を使い切る(`decimal-leading-zero`などは特に有用)
2. 複雑なデザインには`@counter-style`でセマンティクスを守る
3. `::marker`の挙動を理解し、レイアウトへの影響を考慮する
これらを押さえておくだけで、あなたの書くCSSはぐっとプロフェッショナルなものになります。ぜひ、次のプロジェクトのリスト実装で試してみてください。コードの綺麗さは、そのまま実装者の思考の解像度の高さに直結しますから。

コメント