リストマーカーに命を吹き込む:CSSアニメーションの「現実」と「突破口」
フロントエンド開発の現場で、リストのデザインを求められたとき。デザイナーから「リストのポチ(マーカー)を、ホバーしたときにふわりと大きくしたり、色を変えたりしたい」と言われたことはありませんか?
「そんなの簡単だろ」と、安易に `::marker` に `transition` を当てて、ブラウザの挙動に絶望した経験があるのは、きっとあなただけではないはずです。
今日は、CSSの仕様が突きつける残酷な現実と、それをスマートに回避して「現場レベル」のクオリティを叩き出すための技術的アプローチについて深掘りしていきましょう。
—
1. なぜ `::marker` はアニメーションを拒絶するのか
結論から言うと、`::marker` 擬似要素に適用できるCSSプロパティは、仕様上極めて限定的です。
具体的には、`font` 関連、`color`、`content`、そして一部の `animation` 関連のみが許容されています。しかし、ここで最大の落とし穴があります。`transition` はサポートされていないのです。
ブラウザのレンダリングエンジンは、`::marker` を通常のDOM要素とは異なる特別なフローの中で処理しています。DOMツリー上に存在しないこの擬似要素は、スタイルの動的な変更に対して「滑らかな補間(Interpolation)」を行うための計算コストを払うようには設計されていません。
「じゃあ、`@keyframes` ならどうだ?」と試したくなるかもしれませんが、これもまた、多くのブラウザでプロパティの制限により、意図したような滑らかな変化は望めません。
では、どうすればいいのか。答えはシンプルです。「`::marker` を捨て、CSSで自作する」という選択です。
—
2. 現場のベストプラクティス:擬似要素を使ったマーカーの「再構築」
実務で最も堅牢かつ柔軟なのは、`list-style-type: none` でデフォルトのマーカーを消し、`li::before` を使って自作する方法です。これなら、親要素のホバー状態をトリガーにして、`transition` を自由に操ることができます。
以下のコードは、モダンなWebサイトで即戦力となる、「ホバー時にマーカーが弾むように変化する」リストの実装例です。
/ リスト自体のスタイル /
.custom-list {
list-style: none; / デフォルトのマーカーを削除 /
padding: 0;
}
.custom-list li {
position: relative;
padding-left: 1.5rem; / マーカー用のスペースを確保 /
margin-bottom: 0.5rem;
transition: transform 0.2s ease;
}
/ 擬似要素でマーカーを自作 /
.custom-list li::before {
content: “”;
position: absolute;
left: 0;
top: 0.6rem;
width: 0.6rem;
height: 0.6rem;
background-color: #3b82f6; / ブランドカラーを適用 /
border-radius: 50%;
/ アニメーションの定義 /
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
/ ホバー時の挙動 /
.custom-list li:hover::before {
transform: scale(1.3); / 少し大きくする /
background-color: #ef4444; / 色を変える /
box-shadow: 0 0 8px rgba(239, 68, 68, 0.5); / 光彩を放つ /
}
このアプローチの強み
- ブラウザ互換性: 現代のすべてのブラウザで安定して動作します。
- 表現の自由度: `border-radius` や `box-shadow` を駆使すれば、単なる丸だけでなく、複雑な図形やグラデーションも思いのままです。
- アクセシビリティ: `::marker` はスクリーンリーダーに無視されることがありますが、`::before` で装飾的に配置することで、コンテンツの構造を乱さずにデザインを分離できます。
—
3. なぜ「小手先のテクニック」ではなく「設計」が重要なのか
中級レベルからシニアへとステップアップする際、最も重要なのは「どの技術を採用するか」ではなく、「どの技術を採用しないか」を判断する力です。
`::marker` は、マークアップの簡潔さを保つためには優秀です。しかし、UI/UXとしてアニメーションという「動的な体験」を付与するなら、DOM構造をコントロール可能な形(つまり、`li::before` や `span` を使う手法)に書き換えるのがプロの判断です。
もし将来的に「リストのマーカーにSVGを使いたい」という要件が来ても、この構造であれば `background-image` を差し替えるだけで対応できます。「将来的な仕様変更に耐えうる柔軟な構造」こそが、私たちが書くコードの価値です。
最後に:迷ったら「泥臭い」方を選べ
「CSSだけで完結させたい」というエンジニアとしての矜持は素晴らしいものですが、仕様の壁にぶつかったとき、無理にハックを重ねるのは負債の元です。
今回紹介した「デフォルトを消して自作する」という手法は、一見すると原始的で泥臭く感じるかもしれません。しかし、これこそが、複雑なUIを安定して支えるための「正攻法」です。
皆さんのプロジェクトのリストが、明日から少しだけ「滑らか」で「心地よい」ものになることを期待しています。実装で困ったら、いつでもまたここを読み返してください。現場からは以上です。

コメント