Beautiful Custom List Styles Using Modern CSS
Learn to style list markers using the new ::marker pseudo-element
Lists don’t have to be boring.
And with the new
::marker pseudo-element, making them interesting doesn't have to be painful either. The browser support for this pseudo-element used to be spotty, but with its addition in Chrome 86, it'll soon be universal.
I’m going to show you how to make your lists stand out.
We’re going to cover:
- Built-in list styles
- Changing the color of list markers
- Emoji list bullets
- CSS counters
- Custom image bullets
- Fully custom list markers using
Let’s begin by changing the look of list markers using the built-in styles. We do so, by using the
list-style-type property. There are a few style options for both ordered and unordered lists to choose from:
These are just the most common options. The full list can be found on MDN.
::marker pseudo-element lets us change the style of the list marker (bullet/number). using a subset of CSS properties. The allowed properties are:
fontproperties (font-size, font-family etc.)
Let’s see what it can do.
🌈 Changing the Color
The most basic way to make your lists look better, is to change the color of the list markers. We can do that just like we would change the color of normal text.
What if you need to support older browsers? You can apply the color to the
li and wrap the text inside it in another element. Like this:
Or create a fully custom marker with
::before. More on that later.
You might be thinking: Okay, but is changing color all that
::marker can do?
No. Far from it. It lets us to change the content of the list marker, by using the aptly named
You can use any text as
content, including Unicode symbols like the ones above or even emoji...
🔫 Emoji Bullets
As I said above, you can use emoji as list markers.
But you probably don’t want to use the same emoji for every list item. To fix that, we can set our emojis in a
data-* attribute in HTML.
And retrieve them in CSS using the
We can even change the marker’s content on hover using the
And here’s the result.
Okay, but what about ordered lists? Can we change their markers’ content like this?
Custom Ordered Lists
To change the content of an ordered list marker, we need to know which item it belongs to. We need to know its position in the list. That’s where CSS counters come in.
We need to create a counter on the list, and increment it on every list item. Then retrieve the current value of the counter using the
counter() CSS function. We use the result of this function as the value of the
Let’s go through the code, to understand what’s happening.
counter-reset to create a new counter named
list. The name is arbitrary and completely up to you. But why is the property called counter-reset? Because the counter is actually global and we need to reset its value on every list. That's why we have to set it on the
ol and not the list items.
We’ve created our counter, but it’s useless if its value never changes. We need to increment it on every list item. To do that we set
counter-increment: list; on our
Now that we have an auto-incrementing value, we use it in the
content property of our marker. And here's where the magic happens. We can combine the value of our counter with other strings, optionally separated by whitespace.
A few notes:
- In the example, I imported some fonts from Google Fonts. It’s not necessary but I’m using it to distinguish between the list item’s content and the marker.
- Because the marker’s content in the example got pretty long, it was possible for it to go off the screen in some circumstances. That’s why I used
list-style-position: inside;to move the marker inside the list item's box.
- You can put a number after the counter name to start from a different value. It would look something like this:
counter-reset: list 5;and the first three items of that list would have numbers 6, 7, and 8.
- Counters can be used on any html element, not just lists.
Custom Image Bullets
Okay, we can change the color, style, and text content of list markers, but what if we want something completely custom? We’ll have to use images.
To do that, we set an image as the marker’s content using the
url() CSS function.
Fully Custom List Markers
If all of the above options still aren’t enough for you, there’s still one more option. One that allows us to do anything we want with our list markers. It’s more work and a bit of a hack, but it’s useful if all else fails.
We can use the
::before pseudo element to create our own markers. This method allows us to create custom backgrounds for our markers, easily scale image bullets and more.
Clear the defaults
Before we can create our own markers, we have to get rid of the default ones.
This gives us a blank canvas to work with.
Note: This can create accessibility issues, so you should add role=”list” to the list in your HTML
Create the marker
::before you have access to all CSS properties and not just a subset like with
You are however responsible for setting the marker’s content, spacing between the marker and the list item’s text, and proper alignment.
As an example, here’s how to create the objectively best-looking list of all time. Explanations are included in the comments.
The code above results in this:
A few notes:
- Using the background property for the marker’s image allows us to scale and adjust it more easily.
- If you want to create custom image bullets for an unordered list using
background, you have to set
content: ""in order for the marker to be rendered.
That’s all, you’re now a master of list styling.
Thanks for reading. I hope you learned something useful. If you have any questions, ask in the comments. Follow me for more web development tips.
All CSS Background Properties Explained in 5 Minutes
Quick, but Complete Introduction to CSS Background Properties