Styling List Markers With ::marker
HTML lists are everywhere, but until recently, customizing their markers meant turning them off entirely with list-style-type: none and building replacements from scratch. If the default set of unordered markers (disc, circle, square) or the fairly large range of ordered markers didn't fit the design, you had to suppress the native markers, generate your own numbers with ::before and CSS counters, then fiddle with negative text indentation to align everything. It was a painful process.
The ::marker pseudo-element changes that. Supported in Firefox and, thanks to work by Igalia, in Chrome, it gives you a direct handle on the marker itself—no hacks required. Just add a rule like this to your list, and the number styling inherits from ::marker, not the list item text:
li::marker { color: red; font-size: 1.2em; }
That's all it takes. What used to require a complicated workaround is now a straightforward stylesheet rule.
Know the Limitations
Before you rewrite all your list CSS, note that ::marker accepts only a limited set of properties as of February 2021:
- All font properties, such as
font-faceandfont-size colorwhite-space- Internationalization properties:
text-combine-upright,unicode-bidi,direction content- All animation and transition properties
Some browsers expose extra properties, but nearly all additions are text-related, not box-model properties. So if you want numbered markers with shaded circle backgrounds, ::marker won't get you there—you still need the ::before hacks. The specification does note that more properties may be allowed for ::marker in the future, though.
There are also rendering quirks around white-space. Chrome treats all whitespace as white-space: pre and won't let you change it; that's slated for a fix once Chrome's LayoutNG engine ships. Firefox currently ignores any white-space values and treats whitespace like normal-flow text.
Custom Content With Counters
Within those limits, the content property quickly becomes your best friend. You can replace the default period after a number with brackets, dashes, or anything else, mixing counters and strings:
li::marker {
content: "[" counter(list-item) "] ";
}
The space after the closing bracket is deliberate: it creates visible separation between the marker and the list content, since margin and padding properties are off-limits with ::marker. The list-item counter is a special built-in that all CSS counter-aware browsers use for ordered list items—you don't have to define it anywhere else.
Changing Marker Text With list-style-type
If you only need to swap the textual content of a marker and not restyle it, you have another new option beyond ::marker. Browsers now support string values on the list-style-type property itself:
li.warning {
list-style-type:"⚠";
}
This gives a cross-browser way to change marker text without touching generated content. Between ::marker styling and native string values on list-style-type, the day-to-day flexibility for list markers is significantly better than it was—and the specification leaves room for even more capability ahead.



