CSSで、リストの先頭の記号を変える方法

​​CSS​HTML,Playwright,アクセシビリティ

リストの先頭の黒丸や番号は、list-style-type で四角やアルファベット、"✓ " のような好きな文字に変えられます。記号の色と大きさだけを変えるなら ::marker、①②③のような自分で決めた並びにするなら @counter-style を使います。図形を自由に描きたいときは、記号を消して ::before で描きます。

補足

検証環境は Ubuntu 24.04、Node.js 22.23.4、Playwright 1.63.0、Chromium 153 です。HTML と CSS だけのページを Playwright で開き、マーカーの文字(Chromium のアクセシビリティツリーに出る値)、getComputedStyle() の値、スクリーンショットの画素を記録しました。Firefox と Safari、スクリーンリーダーでの読み上げ、画像を記号にする list-style-image は試していません。各ブラウザーの対応バージョンは、互換性データ(@mdn/browser-compat-data 8.1.8)の値です。

縦に並んだ6つの枠に、牛乳と卵などの短いリストがある。上から、初期値の黒丸、黒い四角、「✓」、ピンクの大きな丸、①②③のあとに4つ目だけ「4」になった4項目のリスト、水色の小さな丸
この記事で使う6つの書き方の見た目。各枠の上の文字が、使った CSS

用意された記号に変える:list-style-type

いちばん手軽なのは、list-style-type にキーワードを書く方法です。このプロパティは継承されるので、ul や ol に書くと、中の li すべてに効きます。

css
.square { list-style-type: square; }        /* ■ */
.alpha  { list-style-type: lower-alpha; }   /* a. b. c. */
.kanji  { list-style-type: cjk-ideographic; } /* 一、二、三、 */

検証環境で、Chromium のアクセシビリティツリーから各項目のマーカーの文字を読み出すと、次のようになっていました。

書いた値 マーカーの文字
square ■
lower-alpha a. 、b.
cjk-ideographic 一、、二、

記号をなくすときは list-style-type: none です。

好きな文字を記号にする:list-style-type に文字列を書く

list-style-type には、" で囲んだ文字列も書けます。書いた文字列が、そのまま各項目の先頭に付きます。

css
.check { list-style-type: "✓ "; }

検証環境では、2つの項目のマーカーがどちらも ✓ になりました。後ろに半角の空白を入れたのは、記号と本文の間を空けるためです。検証環境で、記号の右端と本文の左端の間を画素で測ると、"✓ " では 5px 空き、空白なしの "✓" では 0px で、記号と本文がくっついていました。互換性データでは、文字列の値は Chrome と Edge が 79、Firefox が 39、Safari が 14.1(iOS の Safari は 14.5)から使えます。

色と大きさだけ変える:::marker

黒丸のままで、色や大きさだけ変えたいときは、::marker で記号の部分だけを選びます。本文の文字の色は変わりません。

css
.pink li::marker {
  color: #d85878;
  font-size: 1.4em;
}

検証環境では、::marker の計算値が color: rgb(216, 88, 120)、font-size: 28px(本文の 20px の 1.4倍)になりました。本文の color は rgb(31, 42, 48) のままです。スクリーンショットでも、li の左端より左の、記号がある場所にピンクの画素が出ていました。番号付きのリスト(ol)で font-weight: bold を書くと、番号だけが太字(計算値 700)になりました。

記号を大きくすると、そのぶん項目の高さも増えます。検証環境では、同じ 20px の本文で、記号の大きさを変えていない square のリストの li は高さ 29px、記号を 1.4倍にした li は 38px でした。上の見本の画像でも、ピンクの丸のリストだけ、行の間が少し空いています。

::marker で記号の文字を変えると、Safari では効かない

::marker に content を書くと、記号の文字そのものも変えられます。

css
.star li::marker {
  content: "★ ";
  color: #d85878;
}

Chromium では、マーカーの文字が ★ になり、色もピンクになりました。ただし互換性データでは、Safari(iOS の Safari も)の ::marker は対応が一部だけで、「使えるのは color と font-size だけ」と注記されています。

注意

記号の文字は list-style-type の文字列で変え、::marker には色と大きさだけを書くと、互換性データの上では Safari でも効く範囲に収まります。

背景や余白は ::marker に効かない

::marker に書けるプロパティは限られています。MDN の ::marker のページに並んでいるのは、フォント関係、color、content、アニメーションやトランジションなどで、background や padding は入っていません。

css
.markerbg li::marker {
  background: #d85878;
  padding: 0 10px;
}

検証環境でこう書いても、::marker の計算値は background-color: rgba(0, 0, 0, 0)、padding-left: 0px のままでした。画面にもピンクの画素は1つも出ず、記号は黒丸のままです。記号に丸い背景を付けたいような場合は、後で説明する ::before を使います。

①②③のように自分で決めた記号を並べる:@counter-style

項目ごとに違う記号を使いたいときは、@counter-style で記号の並びに名前を付け、その名前を list-style-type に書きます。

css
@counter-style circled {
  system: fixed;
  symbols: "①" "②" "③";
  suffix: " ";
}

.circled { list-style-type: circled; }

symbols が使う記号、suffix が記号の後ろに付ける文字です。system: fixed は、symbols に書いた記号を1つ目から順に1回ずつ使う指定です。

4項目の ol で試すと、マーカーは ① 、② 、③ のあと、4つ目だけ 4 になりました。fixed では記号が3つしかないので、4つ目は表せません。MDN の @counter-style のページのとおり、表せない値は fallback に書いたスタイルで表され、何も書いていなければ decimal(数字)になります。項目の数が決まっていないリストでは、記号を足しておくか、fallback に使いたいスタイルを書いておきます。system: cyclic にすると記号を繰り返して使うので、4つ目は①に戻り、番号としては使えません。

互換性データでは、@counter-style は Chrome と Edge が 91、Firefox が 33、Safari が 17(iOS の Safari も 17)から使えます。

記号の位置を変える:list-style-position

項目の文が2行以上になるとき、記号を本文の外に出すか、本文の中に入れるかで、2行目の始まりが変わります。決めるのは list-style-position です。

css
.inside { list-style-position: inside; }
上下2つの枠に、同じ長い文の項目が1つずつある。点線は li の範囲。上の outside では黒丸が点線の外にあり、2行目は1行目の文字と同じ位置から始まる。下の inside では黒丸が点線の中にあり、2行目は黒丸の真下、点線の左端から始まる
list-style-position の outside(上)と inside(下)。点線が li の範囲

検証環境で、画像とは別の、文字の大きさが 20px で li の左端が x=48 のリストに長い文を入れて、文字の位置を測りました。

list-style-position 記号の左端 1行目の最初の文字 2行目の最初の文字
outside(初期値) x=26(li の外) x=48 x=48
inside x=48(li の中) x=77 x=48

outside では、2行目が1行目の文字とそろいます。inside では、記号が li の中の最初に置かれるので、2行目は記号の真下から始まります。

図形を自由に描く:記号を消して ::before で描く

記号に背景色を付けたい、位置を細かくずらしたい、といった ::marker でできないことは、list-style: none で記号を消し、li::before に図形を描きます。

css
.dot {
  list-style: none;
  padding-left: 0;
}

.dot li {
  position: relative;
  padding-left: 1.2em;
}

.dot li::before {
  content: "";
  position: absolute;
  left: 0.2em;
  top: 0.5em;
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background: #00c8e8;
}

検証環境では、各項目の左に水色の丸が描かれ、Chromium のアクセシビリティツリーからはマーカーがなくなりました(list-style-type や ::marker で変えたリストでは、■ や ✓ のようにマーカーの文字が出ていました)。リスト自体は、Chromium では list のままです。

ただ、MDN の list-style のページのアクセシビリティの節によると、Safari は list-style: none のリストを、<nav> の中にある場合を除いて、アクセシビリティツリーの上でリストとして扱いません。同じページでは、ul に role="list" を付けて、リストの意味を戻す方法が紹介されています。

html
<ul class="dot" role="list">
  <li>牛乳</li>
  <li>卵</li>
</ul>

記号の種類を変えるだけなら list-style-type、色と大きさなら ::marker で足ります。記号を消さないので、Safari でリストの意味が消えることを気にしなくて済みます。::before は、それでは描けない形にしたいときに使います。

​Posted by 86