v135 · css
Timeline list
A step-by-step timeline using ::before::marker — the nested pseudo introduced in Chrome 135. The ::before generates a visual bullet (step number, status badge, or emoji), and ::before::marker suppresses the default list bullet so it doesn't double up. Pure CSS, no wrapper elements required.
::before::marker: checking…
Before: manual workarounds
list-style: none on the parent to kill the marker, then use ::before to fake a bullet. You lose semantic list structure or have to add wrapper elements to restore it.
After: ::before::marker
Keep
list-style-type: disc for accessibility. Style the ::before as a custom counter/badge. Use ::before::marker { content: "" } to suppress just the default marker on that pseudo, not the whole list.
List style
Chrome 135 feature timeline
- Proposal & explainer
- Spec drafted
- Chromium implementation
- Origin trial
- Shipped in Chrome 135
- Other browsers
Toggle step:
/* ::before generates the custom bullet, ::before::marker suppresses the default */
.timeline {
list-style: none;
padding-left: 2rem;
counter-reset: step;
}
.timeline li {
counter-increment: step;
list-style-type: disc; /* keep disc for AT — ::before::marker will hide it visually */
}
.timeline li::before {
content: counter(step);
display: inline-flex;
align-items: center;
justify-content: center;
width: 1.5rem;
height: 1.5rem;
background: black;
color: white;
font-size: 0.65rem;
font-weight: 700;
margin-right: 0.6rem;
}
/* Chrome 135: nested pseudo suppresses the default bullet on ::before only */
.timeline li::before::marker {
content: ""; /* hides the disc that ::before would otherwise also emit */
}