The Simple Task That Wasn't Simple
For years, web developers have struggled with a seemingly simple task: changing the color of list bullets independently from the text. The workaround involved removing default list styling entirely and reconstructing bullets with pseudo-elements--a verbose, error-prone approach. But modern CSS has finally delivered an elegant solution.
The ::marker pseudo-element, now supported across all major browsers, makes bullet customization as straightforward as styling any other element on the page. This feature represents years of specification work and browser implementation efforts, finally giving developers a standardized way to customize list markers without complex workarounds or accessibility compromises.
Understanding how CSS pseudo-elements work is foundational to modern front-end development, enabling developers to create polished, professional interfaces without sacrificing code quality or maintainability.
The Challenge: Why Bullet Color Was Difficult
Before the ::marker pseudo-element arrived, styling list bullets presented a fundamental challenge in CSS. The bullet or number marker in an unordered or ordered list inherits its color from the text content of the list item. This meant developers had two impractical options: either accept bullets with the same color as the text, or completely rebuild list styling from scratch.
The Traditional Workaround
The common approach involved setting list-style: none using ::before on list items and pseudo-elements to create custom bullet representations. This required additional markup, careful spacing adjustments, and often resulted in accessibility issues or inconsistent rendering across browsers.
li {
list-style: none;
padding-inline-start: 1.5rem;
position: relative;
}
li::before {
content: "•";
color: #e63946;
position: absolute;
left: 0;
}
This verbose approach provided control but created maintenance overhead and potential accessibility concerns. Developers found themselves writing elaborate CSS rules just to achieve what should have been a simple styling change. The CSS-Tricks article on this topic captured the community's long-standing frustration with this seemingly basic limitation.
Browser Support: The Turning Point
The ::marker pseudo-element represents years of specification work and browser implementation efforts. Firefox provided early support starting with version 68 in July 2019, while Chrome and Edge followed with version 86 in October 2020. Safari brought support in version 11.1, released in 2018, making the feature widely available across desktop browsers.
Current Browser Coverage
| Browser | Version | Release Date |
|---|---|---|
| Firefox | 68+ | July 2019 |
| Safari | 11.1+ | 2018 |
| Chrome | 86+ | October 2020 |
| Edge | 86+ | October 2020 |
Complete coverage across all modern browsers makes ::marker a safe choice for production websites. The CSS Pseudo-Elements Module Level 4 specification defines the ::marker pseudo-element, establishing it as the standard mechanism for accessing and styling list markers. This specification clarified which CSS properties apply to markers, ensuring consistent behavior across implementations.
The key insight is that markers form a distinct box within list items, separate from the content box, enabling independent styling. As documented by MDN Web Docs, this architectural separation makes the ::marker approach both semantically correct and practically useful.
Basic Syntax And Usage
The ::marker pseudo-element targets the marker box of a list item, which contains the bullet, number, or other list marker. Applying styles to ::marker affects only the marker itself, leaving the list item content unaffected.
The Simple Solution
li::marker {
color: #e63946;
}
This single rule changes the bullet color to a custom red shade while leaving the list text in its original color. The selector can target any list item, whether in unordered lists (ul), ordered lists (ol), or definition lists styled as list items.
Elements Supporting ::marker
The pseudo-element works on elements that have marker boxes by default:
<li>elements in unordered and ordered lists<summary>elements (expand/collapse indicators)- Any element with
display: list-itemapplied
Targeting Specific Items
/* Target first item */
li:first-child::marker {
color: #2a9d8f;
font-size: 1.5rem;
}
/* Target items with specific class */
.feature-list li::marker {
content: "→";
color: #264653;
}
As demonstrated in the web.dev guide on custom bullets, this approach provides clean, maintainable code that respects the semantic structure of HTML lists.
Customizing Bullet Content
Beyond color, the ::marker pseudo-element enables replacing the default bullet character entirely using the content property. Unlike list-style-type, which applies to the entire list uniformly, ::marker with content allows per-item customization.
li::marker {
content: "→";
color: #2a9d8f;
}
li:nth-child(2)::marker {
content: "✓";
color: #2a9d8f;
}
li:nth-child(3)::marker {
content: "★";
color: #2a9d8f;
}
The content property accepts:
- Unicode characters (→, ✓, ★, etc.)
- Emoji bullets for visual flair
- Custom strings for specific branding needs
This approach eliminates the need for background images or SVG sprites for basic bullet customization, reducing page weight and simplifying maintenance. The flexibility of nth-child selectors allows each list item to have a unique marker, enabling creative designs like progress indicators or step-by-step guides. For more advanced CSS techniques that enhance user experience, explore our web design methodology.
Allowable CSS Properties
While ::marker enables powerful customization, the CSS specification limits which properties apply to marker boxes. This restriction exists because markers represent a specific rendering context with unique layout requirements.
Properties That Apply
| Category | Properties |
|---|---|
| Animation | animation-*, transition-* |
| Font | All font-* properties |
| Color | color |
| Content | content |
| Counters | counter-increment, counter-reset, counter-set |
| Text | direction, unicode-bidi, white-space, text-combine-upright |
Properties That Don't Apply
Notably, background, border, padding, and margin do not apply to ::marker. This limitation reflects the marker box's unique rendering context and prevents markers from disrupting list layout.
Practical Implications
Understanding these limitations helps you choose the right approach for each scenario. If you need background colors or borders on your bullets--such as creating highlighted notification lists with colored backgrounds--you'll still use the traditional ::before workaround. However, for the vast majority of use cases involving color, size, and content changes, ::marker provides the simplest and most maintainable solution. The animation and transition support particularly shines for interactive elements like navigation menus and todo lists, where visual feedback enhances user experience without requiring complex markup.
Sizing And Spacing Control
The ::marker pseudo-element supports font-based sizing, which indirectly controls marker size since most markers are text characters.
li {
padding-inline-start: 1.5rem;
}
li::marker {
font-size: 1.25rem;
color: #457b9d;
}
Key points for proper sizing:
- Use
font-sizeorem-based units for marker sizing - Direct
widthandheightproperties don't apply to markers - Control spacing via the list item's
padding-inline-start emunits allow markers to scale proportionally with surrounding text
The separation between marker and content positioning is intentional--it ensures markers maintain proper alignment while giving developers flexibility in how they structure their list content. This approach also improves accessibility, as screen readers can properly interpret list structure regardless of visual styling.
Advanced Techniques: Animations
One of the most exciting capabilities unlocked by ::marker is the ability to animate markers. Since animation and transition properties fully apply to the marker box, developers can create engaging visual effects.
li::marker {
color: #6c757d;
transition: color 0.3s ease;
}
li:hover::marker {
color: #0d6efd;
}
li:nth-child(odd)::marker {
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
}
Real-World Applications
Navigation menus - Create visual feedback when users hover over menu items. The marker can change color or animate to indicate the interactive element, complementing other navigation styling techniques.
Todo lists - Use animated markers to indicate completed tasks. A subtle pulse or color change can reinforce progress without distracting from the content.
Feature lists - Establish visual rhythm in product feature presentations by animating every other marker, drawing attention to key points while maintaining readability.
Step-by-step instructions - Combine numbered list styling with animations to guide users through multi-step processes, highlighting their current position in the sequence.
These animations work particularly well in modern web applications built with frameworks like React or Vue, where state management makes interactive list elements natural to implement.
Comparison: ::marker vs. Traditional Approaches
Why ::marker Is Better
| Aspect | ::marker | ::before workaround |
|---|---|---|
| Syntax | Simple, semantic | Verbose, complex |
| Accessibility | Built-in marker semantics | Requires additional ARIA |
| Browser Support | Full modern support | Universal but verbose |
| Maintenance | Minimal code | Multiple CSS rules |
| Performance | Lightweight | Additional DOM considerations |
When To Use Each Approach
Use ::marker when:
- You need basic color customization
- You want semantic list markup
- Accessibility is a priority
- You're working with modern browsers
Use ::before when:
- You need background colors on bullets
- You require border styling on markers
- Supporting very old browsers is critical
- You need complex marker shapes that text can't achieve
The ::before technique remains valuable when developers need capabilities that ::marker doesn't provide, such as background colors or borders. However, for the vast majority of bullet styling needs--color changes, size adjustments, content replacement, and animations--::marker provides the cleanest solution.
Our web development team regularly applies these techniques when building custom websites, choosing the right approach based on project requirements and browser compatibility needs.
Practical Applications And Best Practices
The ::marker pseudo-element finds applications across diverse web design scenarios. Navigation menus, feature lists, step-by-step instructions, and pricing comparisons all benefit from custom marker styling.
Effective Use Cases
- Navigation menus - Custom bullets for menu items create visual hierarchy and brand consistency
- Feature lists - Visual distinction in content presentations and product comparisons
- Step-by-step instructions - Numbered list styling with custom colors for process documentation
- Pricing comparisons - Custom indicators that align with brand identity
Accessibility Guidelines
- Maintain sufficient color contrast between markers and backgrounds
- Decorative markers shouldn't interfere with screen reader comprehension
- Test with assistive technologies to ensure list structure remains clear
- Consider users who may have custom stylesheets applied
Performance Considerations
- Avoid complex animations on markers in long lists
- Test animation performance across devices and browsers
- Respect user preferences for reduced motion
@media (prefers-reduced-motion: reduce) {
li::marker {
animation: none;
transition: none;
}
}
Following these best practices ensures your list styling enhances rather than hinders the user experience. When implementing custom markers, consider how they integrate with your overall front-end development approach and design system.
Frequently Asked Questions
Conclusion
The ::marker pseudo-element represents a significant advancement in CSS list styling capabilities. After years of workaround-heavy solutions, web developers finally have a standardized, well-supported mechanism for customizing list bullets and numbers.
Key Takeaways
- Simple syntax makes bullet customization accessible to developers of all skill levels
- Full browser support enables production use without compatibility concerns
- Animation support unlocks creative possibilities for interactive lists
- Semantic meaning improves accessibility compared to pseudo-element workarounds
The feature's availability across all major browsers makes it suitable for production use. Developers should embrace this feature while understanding its limitations--particularly around background and border styling--and apply appropriate fallbacks when necessary.
As browsers continue implementing CSS specifications, additional properties may become available for ::marker styling. For now, the current capabilities provide substantial flexibility for creating visually engaging lists while maintaining accessibility and performance.
Whether you're building navigation menus, documentation sites, or product comparison pages, mastering ::marker is a valuable addition to your CSS toolkit. It represents the kind of incremental improvement in web standards that makes frontend development more efficient and maintainable over time. To learn more about building modern, standards-compliant websites, explore our comprehensive web development services.
Sources
- web.dev: Custom bullets with CSS ::marker - Comprehensive guide with examples, browser support data, and interactive demos from Google
- MDN Web Docs: ::marker - Official documentation with technical specifications and property allowances
- CSS-Tricks: Finally, it Will Be Easy to Change the Color of List Bullets - Original article marking the feature's broader browser support
- CSS Pseudo-Elements Module Level 4 Specification - W3C specification defining the ::marker pseudo-element