In my germinating years, the general advice was this:
<ul>
<li><span>List item</span></li>
<!-- ... -->
</ul>
li { color: red; } /* bullet */
li span { color: black; } /* text */
Not terrible, but not great. You’re “resetting” everything at the span level, so it gets more complicated the more you do.
Things are getting much easier. Let’s take a walk through this world getting more modern as we go.
An alternative was to rip off the default list styling and replace it with a pseudo-element.
ul {
list-style: none;
}
li::before {
content: "• ";
color: red;
}
If we need to count, we could do that with CSS counters.
ol {
list-style: none;
counter-reset: my-awesome-counter;
}
ol li {
counter-increment: my-awesome-counter;
}
ol li::before {
content: counter(my-awesome-counter) ". ";
color: red;
}
Quick aside here: this doesn’t help with the color, but you can specify what character to use for the bullet by setting a string, like:
ul {
list-style-type: '✽ ';
}
This is as of Firefox 39 (2015) and Chrome 79 (which comes out Dec 9, 2019).
For ordered lists, there is a ton of language-specific options. And those language styles work for CSS counters as well, which you can learn more about in Hui Jing’s deep dive.
See the Pen
Random CSS counters playground by Chen Hui Jing (@huijing)
on CodePen.
But all the while, we only wanted to select the stupid bullet (or whatever it is) and style it. Now we are starting to be able to do just that.
As of Firefox 68 (July 2019), you can do like:
li::marker {
color: red;
content: "►";
}
…which, as you can see, changes the color and the bullet thing That is definitely the cleanest and easiest way to go, so it’s nice to see progress.
Tejas demonstrates:
See the Pen
::marker example by Tejas (@tejask)
on CodePen.
Manuel Matuzović notes that if you set an element to a list-item
display type, you can use markers on them as well.
h2 {
display: list-item;
}
h2::marker {
color: orange;
content: "☞";
}
Even Safari has support at the time of this writing, so we should lean on Chrome here.
This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.
Desktop
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
86 | 68 | No | 86 | 11.1 |
Mobile / Tablet
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
123 | 124 | 123 | 11.3-11.4 |
How about radio button? Radio button is one of my nightmare
Radio buttons are easy. Hide the input element accessibly (so it’s still available via keyboard and still has an entry in the accessibility tree), and then place a linked
<label>
element after. Style using adjacent sibling selectors.Interesting. Does that selector let you change other properties on the marker, such as positioning or background color or anything like that? Or is it basically limited to character and color?
Well, it could change at some point because the spec is in Working Draft, but it currently says
::marker
styles accept all font and content properties. So, no positioning and background and such, but you might be able to fudge some of that a bit with things likefont-size
and the like. Combine that with, say,list-style-image
and you may gain quite a bit of flexibility there.