CSS symbols() Function

Use the symbols() function to define a counter style from within a property value.

The CSS symbols() function can be used with the list-style-type property and the list-style shorthand property to define a counter style.

The symbols() function gives you more options than the commonly used predefined values such as circle, square, upper-alpha, etc. It allows you to create your own custom counter markers from an image or string (such as a Unicode character). But more importantly, it allows you to define specific rules around how these markers are displayed.

For example, you could specify two alternating Unicode emoji characters to be used as the markers for an unordered list. Like this (see below for the code):

Example of an unordered list using Unicode emojis of apples for bullets.
An unordered list using Unicode emojis of apples for bullets.

The symbols() function is a stripped down alternative to the @counter-style at-rule. The @counter-style at-rule gives you a lot more functionality — you get precise control over creating custom counter markers. However, the symbols() function provides a way to quickly create a counter style directly inline within the property without adding the extra code that an at-rule requires.

The symbols() function is mainly useful for when a counter style is only used once in a stylesheet. In such cases, using the @counter-style at-rule would be overkill — it would result in extra code being used for no extra benefit (unless of course you need more customization options that you can't get with the symbols() function).

If you intend to reuse the same counter style multiple times throughout the style sheet, you should use the @counter-style at-rule instead of the symbols() function. Also, as mentioned there are some things that can only be done with the @counter-style at-rule, so if you find the symbols() function too limited, try the @counter-style at-rule instead.

The symbols() function defines an anonymous counter style with no name. This is because you don't need to refer to the style elsewhere in the style sheet — the style is only used on the property you define it in. The @counter-style at-rule on the other hand, requires that you provide a name for each counter style you define. This allows you to reuse that style by referring to its name.

Official Syntax

The official syntax of the symbols() function is as follows:

Where

So you specify the symbol type, followed by the actual symbol/s (which can be represented by either a string or an image value).

Below is an explanation of each of these values.

Possible Values

cyclic

The cyclic system cycles repeatedly through its provided symbols, looping back to the beginning when it reaches the end of the list of symbols.

This system is ideal for simple bullets (using a single counter symbol), but it can also be used to cycle through multiple symbols if required.

Note that if the system is cyclic, the symbols() function must also contain at least one symbol.

Here's an example of using a value of cyclic.

If your browser supports the symbols() function, the above code could result in a list that looks something like this:

Example of an unordered list styled using the cyclic system.
An unordered list using the cyclic system. This example uses unicode emoji character U+1F347 (grapes) for its marker. If the list was 10, 20, or even 50 items long, each item would use a bunch of grapes as its marker. This is because the cyclic system continously loops back to the beginning when it reaches the end of the list of symbols.

Here's another example — you might remember it from the top of this page. This one uses two symbols. The first symbol is the Unicode code point for a red apple. The second is for a green apple. The cyclic value results in the two emojis looping over and over as required to finish the list.

Here's the code:

And here's the result:

Example of an unordered list using Unicode emojis of apples for bullets.
An unordered list using Unicode emojis of apples for bullets.
fixed

The fixed counter system runs through its list of counter symbols once, then falls back to the fallback counter style.

When using the fixed counter system, the first value is 1. The symbols() function doesn't allow you to change the first value but the @counter-style at-rule does.

Here's an example of using a value of fixed.

If your browser supports the symbols() function, the above code could result in a list that looks something like this:

Example of an unordered list styled using the fixed system.
An unordered list using the fixed system. This example uses three unicode emoji characters for its markers. These only appear for the first three list items. If there are more than three list items, the marker falls back to the fallback counter style (in this case decimal).
symbolic

The symbolic counter system cycles repeatedly through its provided symbols, doubling, tripling, etc. the symbols on each successive pass through the list.

For example, if the original symbols were a, b, and c then on the second pass they would instead be aa, bb, and cc, while on the third they would be aaa, bbb, and ccc, etc.

The symbolic counter system is ideal for footnotes, but could also be used in other contexts.

If the system is symbolic, the symbols() function must also contain at least one counter symbol.

Here's an example of using symbolic.

If your browser supports the symbols() function, the above code could result in a list that looks something like this:

Example of an unordered list styled using the symbolic system.
An unordered list using the symbolic system. This example uses four unicode code points for its markers. If the list contains more than four items, the markers appear again but this time adding another one as required. This continues for each iteration until the end of the list.
alphabetic

The alphabetic counter system interprets the list of counter symbols as digits to an alphabetic numbering system.

For example if a b c is provided under symbols, the resulting list will go a b c then to aa bb cc then aaa bbb ccc etc.

Alphabetic numbering systems do not contain a digit representing 0. The first counter symbol in the list is interpreted as the digit 1, the second as the digit 2, and so on.

If the system is alphabetic, the symbols() function must also contain at least two counter symbols.

Here's an example of using a system value of alphabetic.

If your browser supports the symbols() function, the above code could result in a list that looks something like this:

Example of an unordered list styled using the alphabetic system.
An unordered list using the alphabetic system. This example uses two unicode characters for its markers. As the list progresses these characters are arranged according to the alphabetic numbering system.
numeric

This system interprets the counter symbols as digits in a place-value numbering system. This is similar to the (default) decimal system.

The numeric system is similar to the alphabetic system, with the main difference being that the numeric system allows digits that represent 0. In the numeric system the the first counter symbol in the list is interpreted as the digit 0, the second as the digit 1, and so on.

If the counter system is numeric, the symbols() function must also contain at least two counter symbols.

Here's an example of using a system value of numeric.

If your browser supports the symbols() function, the above code could result in a list that looks something like this:

Example of an unordered list styled using the numeric system.
An unordered list using the numeric system. This example uses two unicode characters for its markers. As the list progresses these characters are arranged according to the alphabetic numbering system.
string
This can be used to specify the value of the symbols descriptor.
image
This can be used to specify the value of the symbols descriptor.

Default Descriptor Values

The following descriptor values apply to counter styles created with the symbols() function:

If you need to change any of these default values, use the @counter-style at-rule instead of the symbols() function.

CSS Specifications

Browser Support

The following table provided by Caniuse.com shows the level of browser support for this feature.