search

Exploring the CSS ::marker Pseudo-Element

The ::marker pseudo-element in CSS lets you style the markers of list items – bullets, numbers, or anything you set via content. No extra HTML or JavaScript needed.

I use it regularly when the default bullet doesn’t fit the design, and it’s one of those small CSS features that makes a real difference in how polished a page feels.

Basic Usage

The basic syntax for using ::marker is straightforward. Apply it to list items in either unordered or ordered lists:

ul li::marker {
  /* Styling for unordered list markers */
}

ol li::marker {
  /* Styling for ordered list markers */
}

The ::marker pseudo-element only supports a limited set of CSS properties: color, font-size, font-family, font-weight, font-style, content, direction, unicode-bidi, and animation-related properties. Properties like background-color, padding, or width do not work with ::marker.

Example 1: Customizing Bullets in an Unordered List

You can change the look of bullets in an unordered list by setting the content property on the marker:

<ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
</ul>
ul {
  list-style: none;
  font-size: 1.2rem;
  font-family: 'Noto Sans Hebrew', sans-serif;
}

li {
  padding-left: 7px;
}

li::marker {
  content: "🔹";
}

The content property replaces the default bullet with a blue diamond emoji.

Here is how it looks:

Live Demo
  • Item 1
  • Item 2
  • Item 3

Example 2: Styling Numbers in an Ordered List

If you want the numbers in an ordered list to appear bold and red, you only need two properties:

<ol>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
</ol>
li::marker {
    font-weight: bold;
    color: red;
}

Here is the result:

Live Demo
  1. Item 1
  2. Item 2
  3. Item 3

Example 3: Advanced ::marker Example

This example builds a clickable task list where the bullet color reflects each task’s status. Since ::marker doesn’t support transforms or transitions, we use ::before instead.

The list items are displayed as flex containers to align the bullet and text. JavaScript toggles the status class on click, and a hover effect scales the bullet up slightly.

HTML

The markup defines a simple unordered list with status classes:

<ul>
    <li class="completed"><span>Task 1: Completed</span></li>
    <li class="in-progress"><span>Task 2: In Progress</span></li>
    <li><span>Task 3: Incomplete</span></li>
</ul>

CSS

The styles use ::before to create colored bullet markers that change based on the task status:

ul {
    list-style: none;
    padding: 0;
    font-family: 'Noto Sans Hebrew', sans-serif;
    font-size: 1.2rem;
}

li {
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    cursor: pointer;
}

li::before {
    content: '•';
    display: inline-block;
    width: 0.7em;
    font-size: 1.5em;
    color: #ddd;
    transition: transform 0.3s, color 0.3s;
}

li.completed::before {
    color: #4CAF50;
}

li.in-progress::before {
    color: #FFC107;
}

li span {
    flex-grow: 1;
}

li:hover::before {
    transform: scale(1.2);
}

JavaScript

A click handler toggles the task status between completed and in-progress:

document.addEventListener('DOMContentLoaded', function() {
    const taskItems = document.querySelectorAll('li');

    taskItems.forEach(function(item) {
        item.addEventListener('click', function() {
            this.classList.toggle('completed');
            this.classList.toggle('in-progress');
        });
    });
});

The Result

Click any task to toggle its status:

Interactive Demo
  • Task 1: Completed
  • Task 2: In Progress
  • Task 3: Incomplete
Click a task to toggle its status

When ::marker does not support the styling you need (such as backgrounds, transforms, or layout properties), using ::before with list-style: none is a common workaround – as demonstrated in this advanced example.

::marker is not the only way to customize list appearance. For styling other text elements, take a look at the ::first-letter pseudo-element.

For more advanced selector techniques, check out the post on CSS4 selectors. And if you’re working with CSS nesting, you can nest ::marker rules right inside the parent selector for cleaner code.

FAQs

Common questions about the CSS ::marker pseudo-element:

What CSS properties can I use with ::marker?
The ::marker pseudo-element supports a limited set of properties: color, font-size, font-family, font-weight, font-style, content, direction, unicode-bidi, and animation-related properties. Properties like background, padding, width, and transform are not supported.
What is the difference between ::marker and ::before for list styling?
::marker targets the existing list marker (bullet or number) and is limited to a small set of properties. ::before is a general pseudo-element that gives you full styling control but requires list-style: none to hide the default marker first. Use ::marker for simple color and font changes, and ::before when you need layout, backgrounds, or transforms.
Can I use emojis or custom characters as list markers?
Yes. You can use the content property on ::marker to set any text, emoji, or Unicode character as the list marker. For example, li::marker { content: "🔹"; } replaces the default bullet with a blue diamond emoji.
Does ::marker work on elements other than list items?
::marker applies to any element with display: list-item. By default, <li> elements have this display value. You can also apply display: list-item to other elements like <summary> or <div> to make ::marker work on them.
Is ::marker supported in all browsers?
Yes. The ::marker pseudo-element is supported in all modern browsers including Chrome, Firefox, Safari, and Edge. For older browsers that do not support it, the default list markers will simply remain unchanged, making it a safe progressive enhancement.

Summary

::marker handles the simple stuff well – color, font, and custom content with minimal code. When you need backgrounds, transforms, or layout control, drop down to ::before with list-style: none.

Both approaches are demonstrated in the live examples above. Pick the one that fits your needs.

Join the Discussion
0 Comments  ]

Leave a Comment

To add code, use the buttons below. For instance, click the PHP button to insert PHP code within the shortcode. If you notice any typos, please let us know!

Savvy WordPress Development official logo