demo · v131

Checklist Markers

Use ::before::marker to style the marker of a ::before pseudo-element independently — turning any element into a stylable list item without touching the DOM.

Note: Your browser does not yet support nested pseudo-element selectors (::before::marker). The checklist below will still work, but marker styling falls back to browser defaults. This feature ships in Chrome 131.

0 of 6 tasks complete

the code

The trick: give ::before display: list-item so it participates in list formatting, then use ::before::marker to style just that marker independently.

/* Make ::before a list item so it generates a marker box */
.task::before {
  content: " ";
  display: list-item;
  list-style-type: "○  ";  /* pending state */
}

/* Target the marker of ::before directly — new in Chrome 131 */
.task::before::marker {
  color: var(--text-muted);
  font-size: 1.1em;
}

/* Swap symbol when task is done */
.task.done::before {
  list-style-type: "✓  ";
}

.task.done::before::marker {
  color: var(--accent-emerald);
  font-size: 1.1em;
}

Prior to nested pseudo-element support, ::before::marker was not a valid selector — you could set list-style-type on the element itself, but you couldn't reach only the marker of a pseudo-element independently from the pseudo-element's own text content.

see also