Skip to content
← Typography Tools

CSS Counter Style Generator

Create custom ordered-list markers with @counter-style: Roman numerals, alphabets, custom symbols, or repeating sequences.

Related Tools

Related Tool
CSS Generator
Related Tool
Responsive Type Calculator
Related Tool
Drop Cap Generator
Related Tool
Typography Scale

What @counter-style unlocks

The CSS @counter-style at-rule defines a custom way of producing the markers in an ordered list. The built-in list-style-type values cover the common cases: decimal, lower-roman, upper-roman, lower-alpha. @counter-style adds everything else: Roman with extended ranges, Greek alphabets, hand-picked emoji sequences, or any arbitrary symbol set. Once defined, the custom style is used by setting list-style-type: my-style-name on the ol element.

Behind the scenes @counter-style maps integers to glyph sequences using a system descriptor. The systems are: cyclic (repeat the symbols), numeric (positional like decimal), alphabetic (positional like A B C with carry to AA AB), symbolic (each symbol used in turn then doubled), additive (Roman-style sum of symbol values), fixed (exact mapping per integer), and extends (inherit and override a built-in).

When you actually need this

Documentation sites with deeply nested lists outgrow the four built-in alphabets fast. Beyond level 4, the spec leaves you with arbitrary characters. @counter-style lets you set up a clean nesting like 1, a, i, 1.a.i with the levels visually distinct.

Brand-conscious editorial sites use custom symbol sets to match their voice. A wine review site might number tasting notes with grape emojis. A trail guide might use mountain symbols. A legal document might need section-mark prefixes (§ 1, § 2). All these are one @counter-style declaration.

Common Use Cases

Technical documentation uses @counter-style to render appendix-style numbering: Appendix A, Appendix B, then sub-items A.1, A.2. Recipe sites use it to set ingredient lists apart from cooking steps with different marker styles. Style guides use it to enforce one numbering pattern across every authored page.

Accessibility-focused teams use @counter-style with caution because not all screen readers announce custom markers. The Generator includes a screen-reader-friendly mode that keeps the visible marker custom while preserving the announced text as the decimal number.

How We Compare

Most CSS reference sites describe @counter-style as a feature without giving you a way to build one. The Generator gives you a live preview as you build, every system explained, and the output CSS in your clipboard with one click.

Compared to copying example @counter-style blocks from MDN and editing them by hand, the Generator validates your input. Putting a symbol outside the supported range, mismatching system and descriptor, or forgetting the range descriptor on an additive system all trigger inline warnings before you ship code that silently falls back to decimal.

Frequently Asked Questions

Which browsers support @counter-style?
All modern browsers since 2022: Chrome 91+, Firefox 33+, Edge 91+, Safari 17+. Safari was the laggard but caught up in September 2023. As of 2026, support is over 95 percent globally. Older browsers fall back to the inherited list-style-type, which is usually decimal, so the page remains readable even where @counter-style is unsupported.
What is the difference between cyclic and symbolic systems?
Cyclic repeats the symbol list. If you define three symbols and have a list of seven items, you get symbol1, symbol2, symbol3, symbol1, symbol2, symbol3, symbol1. Symbolic uses each symbol once, then doubles them: symbol1, symbol2, symbol3, symbol1symbol1, symbol2symbol2, symbol3symbol3. Cyclic is right for repeating bullets. Symbolic is right for footnote markers.
How does the additive system work?
Additive assigns a numeric value to each symbol and sums them to form the marker. Roman numerals are the canonical example: M=1000, D=500, C=100, L=50, X=10, V=5, I=1. The integer 27 becomes XXVII (10+10+5+1+1). The Generator includes Roman as a preset but also lets you build custom additive systems for any numbering scheme.
What is the range descriptor for?
range tells the browser which integer values the counter-style covers. Outside that range, the browser falls back to the fallback descriptor or to decimal. For an upper-roman style that only makes sense up to MMM (3000), you would set range: 1 3000. For an alphabetic style covering A through ZZ, the range is 1 702. Without range, the system handles whatever it can and falls back silently above the limit.
Can I prefix and suffix the marker?
Yes. The prefix descriptor adds a string before the marker. suffix adds a string after. A common pattern is prefix: "Step " suffix: ". " to produce markers like Step 1., Step 2., Step 3.. Prefix and suffix accept any string including spaces and special characters, so you can compose elaborate markers without touching the symbols list.
How does this interact with screen readers?
Mixed. JAWS and NVDA generally announce the visible marker character, which means a custom emoji marker may be announced literally as the emoji name. VoiceOver on Mac and iOS handles it slightly better by announcing the position number alongside the visible marker. For accessibility-first ordered lists, the Generator can output a screen-reader-only span with the numeric position next to the visible custom marker.
Will @counter-style work inside ::marker pseudo-elements?
Yes. The standard way to use a custom counter-style is list-style-type: my-style-name, which the browser applies through ::marker automatically. You can also set list-style-type on individual ::marker pseudo-elements for finer control. Both work consistently across browsers that support @counter-style.
Why does my counter style fall back to decimal sometimes?
Three common reasons. First, the integer is outside the declared range. Second, the system is alphabetic or numeric and you only declared three symbols, which means you ran out. Third, the symbols list contains a character the browser rejects (typically high-codepoint emoji combined with variation selectors). The Generator inline-validates all three at build time.