CSS @Counter-Style Preview
The CSS @counter-style at-rule lets you define custom list marker styles that go far beyond the built-in options like disc, decimal, or lower-roman. With it, you can use any Unicode characters, emoji, or strings as list markers - specifying how they cycle, repeat, or build up numerically - and control every detail including suffix, prefix, padding, and fallback behaviour when the counter runs out of symbols.
This tool gives you two ways to explore counter styles. Use the Custom Builder to define your own @counter-style rule from scratch, choose a system, supply symbols, and tune every descriptor while seeing the result applied to live list previews in real time. Or switch to the Predefined Styles tab to browse and preview all the named counter styles built into CSS, from standard numeric and alphabetic systems through to complex CJK and East Asian scripts.
CSS @Counter-Style Preview
Systems explained
The system descriptor controls the algorithm used to generate counter values. cyclic loops through your symbols repeatedly. numeric treats them as digits in a positional number system. alphabetic works like A, B, โฆ Z, AA, AB. symbolic repeats each symbol an increasing number of times. additive combines weighted symbols (perfect for Roman numerals). fixed uses each symbol once then falls back.
Symbols & strings
The symbols descriptor accepts a space-separated list of values. Bare Unicode characters like โ โ โ work without quotes. String values, including multi-character strings and emoji, must be wrapped in double quotes, e.g. "โ " or "๐". For additive system counters, use additive-symbols instead, pairing each symbol with its numeric weight: 10 X, 5 V, 1 I.
Suffix, prefix & pad
The suffix descriptor defines what appears after the marker - a period and space (". ") is the default. prefix adds content before the marker. Together they let you produce formats like (a) or ยง1. The pad descriptor ensures markers are at least a minimum length, left-padding with a chosen character, useful for producing aligned zero-padded numbers like 001, 002.
Fallback behaviour
When a counter style cannot represent a value, for instance a fixed system that has run out of symbols, or a cyclic style asked to count beyond its range, the fallback descriptor specifies which other counter style to use instead. It defaults to decimal. You can point it at any other predefined style or a custom @counter-style name defined elsewhere in your stylesheet.
Browser support
@counter-style is supported in all modern browsers - Chrome 91+, Firefox 33+, Safari 17+, and Edge 91+. The predefined named styles such as cjk-decimal, hebrew, and the East Asian complex styles have broad support but rendering quality depends on the system's available fonts. Always test complex script styles on target platforms and provide a sensible fallback for older environments.
Using in your CSS
Define your @counter-style block anywhere in your stylesheet, then reference it by name in any list-style-type, list-style, or CSS counter() / counters() function. The generated CSS output is fully ready to paste, it includes both the rule definition and the ul declaration needed to apply it to your list.
@counter-style Descriptors at a Glance
| Descriptor | What it controls | Default | Example |
|---|---|---|---|
system |
The algorithm used to generate counter values | symbolic |
system: cyclic; |
symbols |
The characters or strings used as markers | - | symbols: "โ " "โก" "โข"; |
additive-symbols |
Weighted symbol pairs for the additive system | - | additive-symbols: 10 X, 5 V, 1 I; |
suffix |
Content appended after each marker | ". " |
suffix: ") "; |
prefix |
Content prepended before each marker | "" (empty) |
prefix: "ยง"; |
pad |
Minimum marker length and padding character | 0 "" |
pad: 3 "0"; |
negative |
How negative values are represented | "-" |
negative: "(" ")"; |
fallback |
Counter style to use when values cannot be represented | decimal |
fallback: lower-roman; |
range |
The range of values the style applies to | auto |
range: 1 9; |
speak-as |
How the marker is read aloud by screen readers | auto |
speak-as: numbers; |
Frequently Asked Questions
What is CSS @counter-style?
@counter-style is a CSS at-rule that lets you define custom list marker styles beyond the built-in options like disc, decimal, or lower-roman.
You can use any Unicode characters, emoji, or multi-character strings as markers and control exactly how they cycle, repeat, or build up numerically using a system descriptor.
Once defined, the custom style is referenced by name in any list-style-type property or CSS counter() function.
What is the difference between the cyclic and symbolic systems?
Both loop through your symbols repeatedly, but they do so differently.
cyclic repeats the entire sequence as-is: if you have three symbols A, B, C, the pattern is A, B, C, A, B, C indefinitely.
symbolic repeats each symbol an increasing number of times on each pass: A, B, C, AA, BB, CC, AAA, BBB, CCC - similar to how footnote markers traditionally work.
Use cyclic for simple repeating bullets and symbolic when each "generation" of symbols needs to look visually heavier than the last.
What is the difference between the numeric and alphabetic systems?
numeric treats your symbols as digits in a positional number system. Like decimal which uses 0โ9, a numeric counter with symbols AโJ would count A, B, C โฆ J, BA, BB, BC. Note that the first symbol acts as zero, so it only appears in multi-digit positions.
alphabetic is similar but has no zero - every symbol is used as a significant digit. With symbols AโZ it counts A, B โฆ Z, AA, AB - just like spreadsheet column labels or traditional outline numbering.
How do I use @counter-style in my CSS?
Define the @counter-style block anywhere in your stylesheet, give it a name, and set its descriptors. Then reference that name in a list-style-type declaration on your list element. For example:
@counter-style circled-digits { system: cyclic; symbols: "โ " "โก" "โข"; suffix: " "; }
ul { list-style-type: circled-digits; }
You can also use the custom counter name inside the CSS counter() or counters() functions anywhere you need generated counter values, not just in lists.
What browsers support @counter-style?
@counter-style is supported in all modern browsers: Chrome 91+, Firefox 33+, Edge 91+, and Safari 17+. For older environments or Safari versions before 17, the fallback descriptor ensures a sensible built-in style is used instead. Complex predefined styles for CJK and East Asian scripts have broad support but rendering quality depends on the fonts installed on the user's system, so always test on target platforms and set a meaningful fallback.
What is the fallback descriptor and when does it trigger?
The fallback descriptor specifies which other counter style to use when the current style cannot represent a value.
This happens when a fixed system runs out of symbols, when a value is outside the range defined by the range descriptor, or when the style's algorithm cannot produce a valid representation (for instance, an additive style asked to represent zero with no zero-weight symbol).
It defaults to decimal but can point at any named predefined style or another custom @counter-style defined in your stylesheet.
How do I add a prefix or suffix to my list markers?
Use the prefix and suffix descriptors inside your @counter-style rule.
suffix defines what appears after the marker - the default is a period and a space (". ").
prefix adds content before it - the default is empty.
For example, to produce markers like (1), (2), (3), set prefix: "("; and suffix: ")";.
Note that prefix and suffix content is not selectable in the same way as the marker itself and is purely presentational.
What does the pad descriptor do?
pad ensures that markers are at least a minimum character length, left-padding them with a chosen character when they fall short.
It takes two values: a minimum length and the padding character.
For example, pad: 3 "0"; would render the first nine items as 001, 002 โฆ 009 instead of 1, 2 โฆ 9.
This is useful for producing neatly aligned numbered lists where all markers take up the same visual width.
Can I use emoji as list markers with @counter-style?
Yes. Wrap each emoji in double quotes inside the symbols descriptor, for example: symbols: "๐" "๐" "๐" "๐" "๐";.
Strings in double quotes can be any Unicode content, including multi-character sequences and emoji. Bare Unicode characters (without quotes) also work for single code-point characters like โ โ โ, but quotes are required for anything that could be ambiguous or multi-character.
Browser rendering of emoji markers varies slightly across platforms, so test on your target devices and set a text-based fallback.
What is the difference between @counter-style and list-style-type?
list-style-type is a CSS property applied to a list element that sets which counter style is used for its markers.
It can reference any of the built-in named styles (disc, decimal, lower-roman, and many others) or the name of a custom @counter-style rule you have defined.
Think of @counter-style as the definition of a new marker format, and list-style-type as the instruction to use that format on a specific list.
Page last updated on:
