Control List Markers at a Finer Grain with @counter-style
If you have styled lists in CSS, you have likely run into the ::marker pseudo-element, the list-style property, or custom counters with counter-reset and counter-increment. A less common but powerful tool is the @counter-style at-rule, which offers fine-grained control over how list markers look and behave. Since it became Baseline “newly available” in September 2023, it is well-supported in current browsers.
Target a Single Marker
The fixed system lets you apply a unique marker to just one list item, rather than styling the entire list uniformly.
@counter-style style-fourth-item {
system: fixed 4;
symbols: "💠";
suffix: " ";
}
li {
list-style: style-fourth-item;
}
Map Specific Symbols to Specific Items
With an additive system, you can define which symbols correspond to which list items. The pattern repeats from the start once it reaches the end of its defined cycle. For example, if you pair symbols with six dice faces, the seventh list item starts a new series with two dice, and the total becomes seven.
@counter-style dice {
system: additive;
additive-symbols: 6 "⚅", 5 "⚄", 4 "⚃", 3 "⚂", 2 "⚁", 1 "⚀";
suffix: " ";
}
li {
list-style: dice;
}
Attach Text to Markers
Adding punctuation after a marker previously required a workaround using the list item’s ::before pseudo-element.
ol {
list-style: none;
counter-reset: my-awesome-counter;
li {
counter-increment: my-awesome-counter;
&::before {
content: counter(my-awesome-counter) ") ";
}
}
}
The @counter-style at-rule simplifies this with prefix and suffix descriptors.
@counter-style parentheses {
system: extends decimal;
prefix: "(";
suffix: ") ";
}
Apply Styles to Multiple Item Ranges
The range descriptor limits a counter style to specific list items. For a list with ten items, you might want to style only the first three.
@counter-style single-range {
system: extends upper-roman;
suffix: ".";
range: 1 3;
}
li {
list-style: single-range;
}
You can also build on a custom style with the extend descriptor, as in extending the earlier dice example.
@counter-style dice {
system: additive;
additive-symbols: 6 "⚅", 5 "⚄", 4 "⚃", 3 "⚂", 2 "⚁", 1 "⚀";
suffix: " ";
}
@counter-style single-range {
system: extends dice;
suffix: ".";
range: 1 3;
}
li {
list-style: single-range;
}
Alternatively, the infinite keyword works as the first range value, and as the second value it lets the style count upward for any number of list items. Styling two separate ranges, such as items 1-3 and 6-9, is possible in a single rule.
@counter-style dice {
system: additive;
additive-symbols: 6 "⚅", 5 "⚄", 4 "⚃", 3 "⚂", 2 "⚁", 1 "⚀";
suffix: " ";
}
@counter-style single-range {
system: extends dice;
suffix: ".";
range: infinite 3;
}
li {
list-style: single-range;
}
@counter-style dice {
system: additive;
additive-symbols: 6 "⚅", 5 "⚄", 4 "⚃", 3 "⚂", 2 "⚁", 1 "⚀";
suffix: " ";
}
@counter-style multiple-ranges {
system: extends dice;
suffix: ".";
range: 1 3, 6 9;
}
li {
list-style: multiple-ranges;
}
Align Markers with Padding
Markers can look uneven when a list moves from single-digit to double-digit numbers. Using the pad descriptor, you can add extra characters—spaces, for example—to keep the markers aligned. This approach holds up for lists up to 999 items.
/* adds leading zeroes to list item markers */
@counter-style zero-padded-example {
system: extends decimal;
pad: 3 "0";
}


