@counter-style - CSS At-rule

@counter-style

Summary of characteristics of the @counter-style at-rule

Quick description
Creation of a custom counter that can be used in numbered lists.
Status
Standard
Percentages
Not applicable.
W3C Module
CSS Counter Styles
Document status: CR (Candidate Recommendation)

Description of the @counter-style at-rule.

@counter-style is a CSS language at-rule that lets you set up a completely custom numbering system. This numbering can then be used to create numbered lists or to identify elements like figures, tables, and so on.

The numbering defined by @counter-style can then be applied, often to li tags, using the property list-style-type.

Example of syntax for defining a numbering, which we choose to name demo:

@counter-style demo { system: numeric; prefix: '- '; suffix: ' -'; range:1 infinite; pad:3 '0'; negative:'-'; symbols: 'a' 'b' 'c' 'd' 'e'; fallback:lower-roman; }

And here's how to apply this numbering, using the property list-style-type:

li { list-style-type: demo; }

The name chosen for custom numbering shouldn’t be a keyword already used in CSS related to bulleted or numbered lists. This is, of course, to avoid any conflicts when applying this numbering with list-style-type. So it’s not recommended, and sometimes even forbidden, to name the numbering with names like none, decimal, , square, circle, inside, etc.

Numbering identifiers are case-sensitive. We recommend going with the widely used CSS naming convention: the camel-case, that is, all lowercase with dashes to separate words.

If multiple definitions exist for the same identifier (several @counter-style defining the same identifier), only the last of these definitions is taken into account. All descriptors are replaced, not just the ones mentioned in the second rule.

@counter-style allows you to define all existing numbering styles (see predefined numberings), with a syntax that's more or less long (katakana, Hebrew, Mongolian, Persian, etc.).


Let's look at the syntax now, click for the detailed syntax of each descriptor:

Syntaxes for the negative descriptor.

The negative descriptor defines which characters to add to negative numbers, before or after the number. If the numbering system is cyclic or fixed, the negative descriptor is ignored.

  • @counter-style demo { system: extends decimal; negative: '±'; }

    Indicates that negative numbers must be preceded by the specified character. In our example, we chose the character ±.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten
  • @counter-style demo { system: extends decimal; negative: '(' ')'; }

    Indicates that negative numbers should be displayed in parentheses. The first character is shown before the number, and the second after.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten

Syntaxes for the symbols descriptor.

    The symbols descriptor is among the most important for defining custom numbering: it lets you specify the symbols to use for this numbering.

  • @counter-style demo { symbols: 'a' 'b' 'c' 'd'; }

    A list of characters separated by spaces. If they are single characters, apostrophes or quotation marks can be left out. These characters will be used like digits to build the numbering.

    Here’s, for example, a list built from circled number characters: ①, ②, ③, etc.

    ①②③④⑤⑥⑦⑧⑨⑩

    List of symbols.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten

    Actually, these character sets that represent numbers don’t allow you to recreate correct numeric numbering for large numbers (over 20) because zero doesn’t exist.

    Of course, it's possible to use UTF codes to define characters. But be careful with codes longer than 2 characters; it's better to use a CSS styles-sheet (rather than defining them in the page header) because it's easier to set the character set (with the charset at-rule) in a CSS sheet.

    @counter-style demo { symbols: '\24f5' '\24f6' '\24f7' '\24f8' ...; }
  • @counter-style demo { symbols: 'zero', 'one' 'two' 'three'; }

    A list of words, enclosed in apostrophes or quotation marks, and separated by spaces.

    zero-
    one-
    two-
    three-

    List of symbols.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten
  • @counter-style demo { symbols: url(...) url(...) url(...); }

    A list that uses addresses pointing to images or SVG files.

    The numbering below is built from these images, but for now it only works on Safari. Note: these are images and not the characters representing playing cards like in an example you've already seen

    Card one Card two Card three Card four

    List of images.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten

Syntaxes for the system descriptor.

The system descriptor defines what logic is used for numbering. You immediately think of decimal numbering, but many other numbering systems are possible. For example: numbering in Roman numerals, etc.

In the examples, we give the list of symbols used each time. It should be noted that some types of numbering don't need a symbol declaration: numeric, alphabetic for example. However, this allows the characteristics of each type of numbering to stand out better.

  • @counter-style demo { system: numeric; ou decimal }

    The first symbol provided is associated with the value 0. So it doesn’t appear at the start of numbering (we start at 1). Once you reach the last symbol, the numbering continues following the logic of numerical numbering.

    🂠
    🃁
    🃂
    🃃
    🃄
    🃅

    List of symbols.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten
    system:numeric;
  • @counter-style demo { system: alphabetic; }

    The first symbol given is associated with the value 1. By the time you get to the last symbol, the numbering continues following the logic of alphabetical numbering.

    🂠
    🃁
    🃂
    🃃
    🃄
    🃅

    List of symbols.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten
    system:alphabetic;
  • @counter-style demo { system: cyclic; }

    Use all the provided symbols one after the other and start over at the first one after you pass the last.

    🂠
    🃁
    🃂
    🃃
    🃄
    🃅

    List of symbols.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten
    system:cyclic;
  • @counter-style demo { system: fixed 4; }

    Use all the symbols provided one after the other and then continue with the numbering defined by the fallback descriptor. If the latter isn’t specified, the numbering continues in regular decimal.

    The optional integer that follows indicates the value of the first symbol. If it's omitted, the value of the first symbol is 1.

    List of symbols.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten
    system:fixed;
    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten
    system:fixed 4;
  • @counter-style demo { system: symbolic; }

    Use all the symbols provided one after the other, then continue by doubling them, then tripling them, and so on.

    List of symbols.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten
    system:symbolic;
  • @counter-style demo { system: additive; }

    A type of numbering similar to Roman numerals. It requires that a numeric value be assigned to each symbol. It's the additive-symbols descriptor that allows for this assignment (it replaces the symbols descriptor). The symbols must be listed in reverse order of their value.
    Example: additive-symbols: 10 'Ⅹ', 9 'Ⅸ', 5 'Ⅴ', 4 'Ⅳ', 1 'Ⅰ';

    If a number can't be represented in this numbering system (like negative numbers), the fallback descriptor is used. If fallback isn't set, the numbering is done in regular decimal.


    10

    9

    5

    4

    1

    List of symbols
    and their value.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten
    system:additive;


    It's worth noting that it's necessary to define the symbols for 4 and 9 even though they're made up of two existing symbols (I and V for 4). This is because the additive system doesn't do subtractions. Similarly, you'd need to define the symbols for 40, 90, 400, and so on.

  • @counter-style demo { system: extends lower-roman; prefix:'-'; suffix'-'; }

    Allows you to use an existing numbering by changing some of its settings. In the example, we use the standard lower-roman numbering but add a dash before and after the number.

    When extends is specified, the symbols and additive-symbols descriptors are forbidden.

Syntaxes pour les descripteurs prefix et suffix.

These two descriptors indicate one or more characters that will be added before (prefix) or after the number (suffix).

  • @counter-style demo { system: extends decimal; prefix:'- '; suffix:' - '; }

    This example generates numbers that look like - 1 - .
    Page numbers are often shown like this.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten

Syntaxes for the range and fallback descriptors.

range sets the limits that should not be exceeded for numbering, and the bounds are included.
If the counter goes beyond these limits, the numbering reverts to the style defined by the fallback descriptor. If that's not set, numbering continues in the usual numeric style. Example: range:1 10; means that numbering works from number 1 up to and including number 10.

fallback is also useful when a number can't be represented by the chosen system. For example, negative numbers don't exist in alphabetic, symbolic, and additive systems.

  • @counter-style demo { symbols: '①' '②' '③' '④' '⑤' '⑥' '⑦' '⑧' '⑨'; range: 1 9; fallback: decimal; }

    This syntax example shows that the numbering continues in the usual decimal mode if you reach the limit set to 9 by range.

    In the range descriptor, the first number has to be smaller than the second, otherwise the descriptor definition is invalid.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten


    Browsers are supposed to spot loops created with fallback and not get stuck in endless calculations. For example, a demo1 style that has demo2 as its fallback, and this one then refers back to demo1 through its fallback.

    @counter-style demo1 { ...; fallback: demo2; } @counter-style demo2 { ...; fallback: demo1; }
  • @counter-style demo { range: auto; }

    The auto value is interpreted differently by browsers depending on the numbering system chosen:

    • For cyclic, numeric, and fixed numbering systems, the counting range is not limited, neither for negative numbers nor for positive numbers.
    • For alphabetic and symbolic numbering systems, the numbering range goes from 1 to infinity (no negative numbers).
    • For the additive numbering system, the range goes from 0 to infinity (no negative numbers).

Syntaxes for the pad descriptor.

This descriptor defines over how many characters the numbering should be displayed, and which character will be used for padding. Commonly, the padding character will be zero or a space.

  • @counter-style demo { system: numeric; pad: 2 '0'; }

    This syntax indicates a 2-digit numbering, with a leading zero if needed: 01, 85, 08, etc. The number is a positive integer or zero.
    Be careful, the negative number symbol is counted.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten

Syntaxes for the additive-symbols descriptor.

additive-symbols` is only useful for the `additive` numbering system. This setting links a numeric value to each symbol. Each number will be made by adding up one or more of these values. It's the principle behind Roman numerals. The symbols should be listed in descending order of their value.

It's not necessary to specify the symbols clause when additive-symbols is used.

  • @counter-style demo { system: additive; symbols: 'I' 'V' 'X'; additive-symbols: 10 'Ⅹ', 9 'Ⅸ', 5 'Ⅴ', 4 'Ⅳ', 1 'Ⅰ'; }

    This syntax defines the beginning of numbering in Roman numerals, where X is 10, is 9, V is 5, is 4, and I is 1.
    The symbols must be written in descending order of their value.
    There is no zero in this kind of numbering.

    • One
    • Two
    • Three
    • Four
    • Five
    • Six
    • Seven
    • Eight
    • Nine
    • Ten

Syntaxes for the speak-as descriptor.

This setting controls how the dialing sounds are played back. Of course, this assumes you have a browser with text-to-speech.

  • @counter-style demo { speak-as: auto; }

    The browser decides the best way to pronounce the numbering, depending on the numbering system chosen:
    alphabetic: the number will be spelled out.
    cyclic: beep sound.
    In other cases, the number will be read as a number.

  • @counter-style demo { speak-as: bullet; }

    The navigator transmits the numbering through a beep.

  • @counter-style demo { speak-as: numbers; }

    During the sound playback, the number is read as a numeric value.

  • @counter-style demo { speak-as: words; }

    The number is read like a word.

  • @counter-style demo { speak-as: spell-out; }

    The number will be spelled out character by character.

  • @counter-style demo { speak-as: xxx; }

    The pronunciation of the numbers will be the one defined by the numbering called xxx. This can be useful when a numbering uses unpronounceable symbols, like images or special characters.

Examples of use of the @counter-style at-rule.

Binary numbering.

Binary is a numbering system that only uses the digits 0 and 1, but it works like a regular numbering system.

  1. One
  2. Two
  3. Three
  4. Four
  5. Fice
  6. Six
  7. Seven
  8. Eight
  9. Nine
  10. Ten
  11. Eleven
  12. Twelve
  13. Thirteen
  14. Fourteen
  15. Fifteen

A Morse code numbering.

Probably not very useful since Morse code has been abandoned even by the military. But it's a good illustration for a custom counting system.

  1. One
  2. Two
  3. Three
  4. Four
  5. Fice
  6. Six
  7. Seven
  8. Eight
  9. Nine
  10. Ten
  11. Eleven
  12. Twelve
  13. Thirteen
  14. Fourteen
  15. Fifteen

Numbering with playing cards.

The cards are characters from the UTF-8 game (see our tool UTF character codes). They are not images because support for images is still weak on most browsers.

  1. One
  2. Two
  3. Three
  4. Four
  5. Fice
  6. Six
  7. Seven
  8. Eight
  9. Nine
  10. Ten
  11. Eleven
  12. Twelve
  13. Thirteen
  14. Fourteen
  15. Fifteen

Interactive example with @counter-style.

The simulator below builds numberings using the four playing card symbols, in this order. These are UTF-8 characters. Watch how each system continues the numbering beyond 4.

 

 
 

1
 

3
 

7
 

For additive numbering, only 3 symbols are used, with the numeric values shown above.
 

list-style-type :
  1. January
  2. February
  3. March
  4. April
  5. May
  6. June
  7. July
  8. August
  9. September
  10. October
  11. November
  12. December

Browsers compatibility with the @counter-style at-rule.

The @counter-style at-rule is now well recognized by current browsers, but there are still some compatibility issues with certain descriptors like symbols.

Column 1
Support by browsers for the @counter-style directive which allows the definition of custom counters.
Column 2
Support for the symbols descriptor used with the @counter-style at rule (especially the syntax with url() that allows using images as symbols).
Column 3
Support by browsers for the speak-as descriptor for the @counter-style rule.

Notes:

(1) Partial support because support for symbols-images is missing.

(2) Does not accept an image as a value for symbols.

1
@counter-style
at-rule
2
symbols
descriptor
3
speak-as
descriptor
Estimated overall support.
0%
14%
80%

Browsers on computers :

Mobile browsers :

Outdated or marginal browsers :

Internet Explorer

Baidu Browser

QQ Browser

Opéra Mobile

Firefox

Chrome

Safari

Edge

Opéra

Chrome pour Androïd

Safari sur IOS

Samsung Internet

UC Browser pour Androïd

Androïd Brower

Firefox pour Androïd

KaiOS Browser

Opéra mini

Evolution of the @counter-style at-rule.

  • CSS Counter Styles Level 3

    Regarding @counter-style Introduction of custom numbering and counters, and the @counter-style at-rule.
    WD
    October 09, 2012
    Working Draft.
    CR
    February 03, 2015
    Candidate Recommendation.
    PR
    REC

See also, about custom numbering.

The directive @counter-style is described in the specification "CSS Counter Styles".
These other definitions are also presented in the same module.

Functions:

symbols()
Defines the symbols used for custom numbering, as well as the type of numbering (numeric, alphabetical, and so on).

At-rules:

@counter-style
Creation of a custom counter that can be used in numbered lists.

Descriptors :

additive-symbols
A @counter-style descriptor, which defines the value of each of the symbols in a custom numbering.
fallback
When used with @counter-style, sets an override numbering when the counter goes outside the boundaries of a custom numbering.
negative
Descriptor usable with the @counter-style at-rule. Defines the symbol to be used for negative numbers (custom numbering).
prefix
A descriptor that can be used with the @counter-style at-rule to define the character(s) to be added before the number, as part of a custom numbering.
range
A descriptor that can be used with the @counter-style directive to define the validity range of a custom numbering.
suffix
Descriptor usable with @counter-style. Defines the characters to be added after the number, in a custom numbering.
symbols
A descriptor that can be used with the @counter-style at-rule. It lists the symbols to be used in custom numbering. Not to be confused with the function of the same name.
system
Sets the numbering system to use for custom numbering.