Abstract

This module introduces the @counter-style rule, which allows authors to define their own custom counter styles for use with CSS list-marker and generated-content counters [CSS3LIST]. It also predefines a set of common counter styles, including the ones present in CSS2 and CSS2.1.

CSS is a language for describing the rendering of structured documents
(such as HTML and XML)
on screen, on paper, in speech, etc.

Status of this document

This section describes the status of this document at the time of its publication.
Other documents may supersede this document.
A list of current W3C publications and the latest revision of this technical report
can be found in the W3C technical reports index at http://www.w3.org/TR/.

Publication as a Candidate Recommendation does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

The (archived)
public mailing list www-style@w3.org
(see instructions)
is preferred for discussion of this specification.
When sending e-mail,
please put the text “css-counter-styles” in the subject,
preferably like this:
“[css-counter-styles] …summary of comment…”

1.
Introduction

CSS 1 defined a handful of useful counter styles based on the styles that HTML traditionally allowed on ordered and unordered lists.
While this was expanded slightly by CSS2.1,
it doesn’t address the needs of worldwide typography.

This module introduces the @counter-style rule which allows CSS to address this in an open-ended manner,
by allowing the author to define their own counter styles.
These styles can then be used in the list-style-type property
or in the counter() and counters() functions.
It also defines some additional predefined counter styles,
particularly ones which are common but complicated to represent with @counter-style.

2.
Counter Styles

A counter style defines how to convert a counter value into a string.
Counter styles are composed of:

a name,
to identify the style

an algorithm,
which transforms integer counter values into a basic string representation

a negative sign,
which is prepended or appended to the representation of a negative counter value.

a prefix,
to prepend to the representation

a suffix
to append to the representation

a range,
which limits the values that a counter style handles

a spoken form,
which describes how to read out the counter style in a speech synthesizer

and a fallback style,
to render the representation with when the counter value is outside the counter style’s range
or the counter style otherwise can’t render the counter value

When asked to generate a counter representation
using a particular counter style for a particular counter value,
follow these steps:

If the counter style is unknown,
exit this algorithm and instead generate a counter representation
using the decimal style and the same counter value.

If the counter value is outside the range of the counter style,
exit this algorithm and instead generate a counter representation
using the counter style’s fallback style and the same counter value.

Using the counter value and the counter algorithm for the counter style,
generate an initial representation for the counter value.
If the counter value is negative
and the counter style uses a negative sign,
instead generate an initial representation using the absolute value of the counter value.

Prepend symbols to the representation as specified in the pad descriptor.

If the counter value is negative
and the counter style uses a negative sign,
wrap the representation in the counter style’s negative sign
as specified in the negative descriptor.

Return the representation.

Note: the prefix and suffix don’t play a part in this algorithm.
This is intentional;
the prefix and suffix aren’t part of the string returned by the counter() or counters() functions.
Instead, the prefix and suffix are added by the algorithm that constructs the value of the content property
for the ::marker pseudo-element.
This also implies that the prefix and suffix always come from the specified counter-style,
even if the actual representation is constructed by a fallback style.

Some values of system (symbolic, additive)
and some descriptors (pad)
can generate representations with size linear to an author-supplied number.
This can potentially be abused to generate excessively large representations
and consume undue amounts of the user’s memory or even hang their browser.
User agents must support representations at least 60 Unicode codepoints long,
but they may choose to instead use the fallback style for representations that would be longer than 60 codepoints.

The @counter-style rule allows authors to define a custom counter style.
The components of a counter style are specified by descriptors in the @counter-style rule.
The algorithm is specified implicitly by a combination of the system, symbols, and additive-symbols properties.

Note: Note that <custom-ident> also automatically excludes the CSS-wide keywords.
In addition, some names, like inside,
are valid as counter style names,
but conflict with the existing values of properties like list-style,
and so won’t be usable there.

Counter style names are case-sensitive.
However, the names defined in this specification are ASCII lower-cased on parse
wherever they are used as counter styles, e.g.
in the list-style set of properties,
in the @counter-style rule,
and in the counter() functions.

Each @counter-style rule specifies a value for every counter-style descriptor,
either implicitly or explicitly.
Those not given explicit value in the rule take the initial value listed with each descriptor in this specification.
These descriptors apply solely within the context of the @counter-style rule in which they are defined,
and do not apply to document language elements.
There is no notion of which elements the descriptors apply to or whether the values are inherited by child elements.
When a given descriptor occurs multiple times in a given @counter-style rule,
only the last specified value is used;
all prior values for that descriptor must be ignored.

Defining a @counter-style makes it available to the entire document in which it is included.
If multiple @counter-style rules are defined with the same name,
only one wins,
according to standard cascade rules.
@counter-style rules cascade "atomically":
if one replaces another of the same name,
it replaces it entirely,
rather than just replacing the specific descriptors it specifies.

Note: Note that even the predefined counter styles can be overridden;
the UA stylesheet occurs before any other stylesheets,
so the predefined ones always lose in the cascade.

This at-rule conforms with the forward-compatible parsing requirement of CSS;
conformant parsers that don’t understand these rules will ignore them without error.
Any descriptors that are not recognized or implemented by a given user agent,
or whose value does not match the grammars given here or in a future version of this specification,
must be ignored in their entirety;
they do not make the @counter-style rule invalid.

The system descriptor specifies which algorithm will be used to construct
the counter’s representation based on the counter value. For example,
cyclic counter styles just cycle through their symbols repeatedly,
while numeric counter styles interpret their symbols as digits and
build their representation accordingly. The systems are defined as follows:

The cyclic counter system cycles repeatedly through its provided symbols,
looping back to the beginning when it reaches the end of the list.
It can be used for simple bullets
(just provide a single counter symbol),
or for cycling through multiple symbols.
The first counter symbol is used as the representation of the value 1,
the second counter symbol (if it exists) is used as the representation of the value 2, etc.

If the system is cyclic,
the symbols descriptor must contain at least one counter symbol,
or else the @counter-style rule is invalid.
This system is defined over all counter values.

A "triangle bullet" counter style can be defined as:

@counter-style triangle {
system: cyclic;
symbols: ‣;
suffix: " ";
}

It will then produce lists that look like:

‣ One
‣ Two
‣ Three

If there are Ncounter symbols
and a representation is being constructed for the integer value,
the representation is the counter symbol
at index ( (value-1) mod N)
of the list of counter symbols (0-indexed).

The fixed counter system runs through its list of counter symbols once,
then falls back.
It is useful for representing counter styles that only have a finite number of representations.
For example, Unicode defines several limited-length runs of special characters meant for lists,
such as circled digits.

If the system is fixed,
the symbols descriptor must contain at least one counter symbol,
or else the @counter-style rule is invalid.
This system is defined over counter values in a finite range,
starting with the first symbol value and having a length equal to the length of the list of counter symbols.

When this system is specified,
it may optionally have an integer provided after it,
which sets the first symbol value.
If it is omitted, the first symbol value is 1.

The first counter symbol is the representation for the first symbol value,
and subsequent counter values are represented by subsequent counter symbols.
Once the list of counter symbols is exhausted,
further values cannot be represented by this counter style,
and must instead be represented by the fallback counter style.

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 "*" and "†",
then on the second pass they would instead be "**" and "††",
while on the third they would be "***"and "†††", etc.
It can be used for footnote-style markers,
and is also sometimes used for alphabetic-style lists for a slightly different presentation than what the alphabetic system presents.

If the system is symbolic,
the symbols descriptor must contain at least one counter symbol,
or else the @counter-style rule is invalid.
This system is defined only over strictly positive counter values.

Some style guides mandate a list numbering that looks similar to upper-alpha,
but repeats differently after the first 26 values,
instead going "AA", "BB", "CC", etc.
This can be achieved with the symbolic system:

This style is identical to upper-alpha through the first 27 values,
but they diverge after that, with upper-alpha going "AB", "AC", "AD", etc.
Starting at the 53rd value, upper-alpha goes "BA", "BB", "BC", etc.,
while this style jumps into triple digits with "AAA", "BBB", "CCC", etc.

To construct the representation, run the following algorithm:

Let N be the length of the list of counter symbols,
value initially be the counter value,
S initially be the empty string,
and symbol(n) be the nth counter symbol in the list of counter symbols (0-indexed).

Let the chosen symbol be symbol( (value - 1) mod N).

Let the representation length be ceil( value / N ).

Append the chosen symbol to S a number of times equal to the representation length.

The alphabetic counter system interprets the list of counter symbols as digits to an alphabetic numbering system,
similar to the default lower-alpha counter style,
which wraps from "a", "b", "c", to "aa", "ab", "ac".
Alphabetic numbering systems do not contain a digit representing 0;
so the first value when a new digit is added is composed solely of the first digit.
Alphabetic numbering systems are commonly used for lists,
and also appear in many spreadsheet programs to number columns.
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 descriptor must contain at least two counter symbols,
or else the @counter-style rule is invalid.
This system is defined only over strictly positive counter values.

Note: This example requires support for SVG images to display correctly.

If there are Ncounter symbols,
the representation is a base N alphabetic number using the counter symbols as digits.
To construct the representation, run the following algorithm:

Let N be the length of the list of counter symbols,
value initially be the counter value,
S initially be the empty string,
and symbol(n) be the nth counter symbol in the list of counter symbols (0-indexed).

The numeric counter system interprets the list of counter symbols
as digits to a "place-value" numbering system,
similar to the default decimal counter style.
The first counter symbol in the list is interpreted as the digit 0,
the second as the digit 1,
and so on.

If the system is numeric,
the symbols descriptor must contain at least two counter symbols,
or else the @counter-style rule is invalid.
This system is defined over all counter values.

A "trinary" counter style can be defined as:

@counter-style trinary {
system: numeric;
symbols: '0' '1' '2';
}

It will then produce lists that look like:

1. One
2. Two
10. Three
11. Four
12. Five
20. Six

If there are Ncounter symbols,
the representation is a base N number using the counter symbols as digits.
To construct the representation, run the following algorithm:

Let N be the length of the list of counter symbols,
value initially be the counter value,
S initially be the empty string,
and symbol(n) be the nth counter symbol in the list of counter symbols (0-indexed).

The additive counter system is used to represent "sign-value" numbering systems,
which, rather than using reusing digits in different positions to change their value,
define additional digits with much larger values,
so that the value of the number can be obtained by adding all the digits together.
This is used in Roman numerals
and other numbering systems around the world.

If the system is additive,
the additive-symbols descriptor must contain at least one additive tuple,
or else the @counter-style rule is invalid.
This system is nominally defined over all counter values
(see algorithm, below, for exact details).

Let value initially be the counter value,
S initially be the empty string,
and symbol list initially be the list of additive tuples.

If value is initially 0, and there is an additive tuple with a weight of 0, append that tuple’s counter symbol to S and return S.

While value is greater than 0 and there are elements left in the symbol list:

Pop the first additive tuple from the symbol list.
This is the current tuple.

Append the current tuple’s counter symbol to Sfloor( value / current tuple’s weight )
times (this may be 0).

Decrement value by the current tuple’s weight multiplied
by the number of times the current tuple was appended to S
in the previous step.

If the loop ended because value is 0, return S. Otherwise, the given counter value cannot be represented by this counter style, and must instead be represented by the fallback counter style.

Note: All of the predefined additive @counter-style rules in this specification
produce representations for every value in their range,
but it’s possible to produce values for additive-symbols that will fail to find a representation
with the algorithm defined above,
even though theoretically a representation could be found.
For example, if a @counter-style was defined with additive-symbols: 3 "a", 2 "b";,
the algorithm defined above will fail to find a representation for a counter value of 4,
even though theoretically a "bb" representation would work.
While unfortunate, this is required to maintain the property that the algorithm runs in linear time
relative to the size of the counter value.

The extends system allows an author to use the algorithm of another counter style,
but alter other aspects,
such as the negative sign or the suffix.
If a counter style uses the extends system,
any unspecified descriptors must be taken from the extended counter style specified,
rather than taking their initial values.

If the specified counter style name isn’t the name of any currently-defined counter style,
it must be treated as if it was extending the decimal counter style.
If one or more @counter-style rules form a cycle with their extends values,
all of the counter styles participating in the cycle
must be treated as if they were extending the decimal counter style instead.

For example, if you wanted a counter style that was identical to decimal,
but used a parenthesis rather than a period after it, like:

1) first item
2) second item
3) third item

Rather than writing up an entirely new counter style,
this can be done by just extending decimal:

The negative descriptor defines how to alter the representation when
the counter value is negative.

The first <symbol> in the value is prepended to the representation when the
counter value is negative. The second <symbol>, if specified, is appended
to the representation when the counter value is negative.

For example, specifying negative: "(" ")"; will make negative
values be wrapped in parentheses, which is sometimes used in financial
contexts, like "(2) (1) 0 1 2 3...".

The prefix descriptor specifies a <symbol> that is prepended to the
marker representation. Prefixes are only added by the algorithm for constructing
the default contents of the ::marker pseudo-element; the prefix is not
added automatically when the counter() or counters() functions are used.
Prefixes come before any negative sign.

The suffix descriptor specifies a <symbol> that is appended to the
marker representation. Suffixes are only added by the algorithm for constructing
the default contents of the ::marker pseudo-element; the suffix is not
added automatically when the counter() or counters() functions are used.
Suffixes are added to the representation after negative signs.

The range descriptor defines the ranges over which the counter style is defined.
If a counter style is used to represent a counter value outside of its ranges,
the counter style instead drops down to its fallback counter style.

auto

The range depends on the counter system:

For cyclic, numeric, and fixed systems,
the range is negative infinity to positive infinity.

This defines a comma-separated list of ranges.
For each individual range,
the first value is the lower bound
and the second value is the upper bound.
This range is inclusive - it contains both the lower and upper bound numbers.
If infinite is used as the first value in a range,
it represents negative infinity;
if used as the second value,
it represents positive infinity.
The range of the counter style is the union of all the ranges defined in the list.

If the lower bound of any range is higher than the upper bound,
the entire descriptor is invalid and must be ignored.

Implementations must support ranges with a lower bound of at least -215
and an upper bound of at least 215-1
(the range of a signed 2-byte int).
They may support higher ranges.
If any specified bound is outside of the implementation’s supported bounds,
it must be treated as the closest bound that the implementation does support.

The pad descriptor allows an author to specify a "fixed-width" counter style,
where representations shorter than the pad value are padded with a particular <symbol>.
Representations larger than the specified pad value are constructed as normal.

If difference is greater than zero,
prepend difference copies of the specified <symbol> to the representation.

The <integer> must be non-negative.
A negative value is a syntax error.

The most common example of "fixed-width" numbering is zero-padded decimal numbering.
If an author knows that the numbers used will be less than a thousand, for example,
it can be zero-padded with a simple pad: 3 "0"; descriptor,
ensuring that all of the representations are 3 digits wide.

This will cause, for example,
1 to be represented as "001",
20 to be represented as "020",
300 to be represented as "300",
4000 to be represented as "4000",
and -5 to be represented as "-05".

The fallback descriptor specifies a fallback counter style to be used
when the current counter style can’t create a representation for a given
counter value. For example, if a counter style defined with a range of 1-10
is asked to represent a counter value of 11, the counter value’s representation
is instead constructed with the fallback counter style (or possibly the
fallback style’s fallback style, if the fallback style can’t represent that
value, etc.).

If the value of the fallback descriptor isn’t the name of any
currently-defined counter style, the used value of the fallback descriptor
is decimal instead. Similarly, while following fallbacks to find
a counter style that can render the given counter value, if a loop in the
specified fallbacks is detected, the decimal style must be used instead.

Note that it is not necessarily an error to specify fallback
loops. For example, if an author desires a counter style with significantly
different representations for even and odd counter values, they may find it
easiest to define one style that can only represent odd values and one that
can only represent even values, and specify each as the fallback for the
other one. Though the fallback graph is circular, at no point do you encounter
a loop while following these fallbacks - every counter value is represented
by one or the other counter style.

Some counter systems specify that the symbols descriptor must have at
least two entries. If the counter style’s system is such, and the symbols
descriptor has only a single entry, the counter style is invalid and must
be ignored.

Each entry in the symbols descriptor’s value defines a counter symbol,
which is interpreted differently based on the counter style’s system. Each
entry in the additive-symbols descriptor’s value defines an additive tuple,
which consists of a counter symbol and a non-negative integer weight.
Each weight must be a non-negative integer, and the additive tuples
must be specified in order of descending weight; otherwise, the @counter-style
is invalid and must be ignored.

Counter symbols may be strings, images, or identifiers,
and the three types can be mixed in a single descriptor.
Counter representations are constructed by concatenating counter symbols together.
Identifiers are rendered as strings containing the same characters.
Images are rendered as inline replaced elements.
The default object size of an image counter symbol is a 1em by 1em square.

Note: If using identifiers rather than strings to define the symbols,
be aware of the syntax of identifiers.
In particular, ascii non-letters like "*" are not identifiers,
and so must be quoted in a string.
Hex escapes,
used in several of the counter styles defined in this specification,
"eat" the following space
(to allow a digit to follow a hex escape without ambiguity),
so two spaces must be put after a hex escape
to separate it from the following one,
or else they’ll be considered adjacent,
and part of the same identifier.

A counter style can be constructed with a meaning that is obvious visually,
but impossible to meaningfully represent via a speech synthesizer,
or possible but nonsensical when naively read out.
The speak-as descriptor describes how to synthesize the spoken form of a counter formatted with the given counter style.
Values have the following meanings:

The UA speaks a UA-defined phrase or audio cue that represents an unordered list item being read out.

numbers

The counter’s value is spoken as a number in the document language.

words

Generate a counter representation for the value as normal,
then speak it as normal text in the document language.

spell-out

Generate a counter representation for the value as normal,
then spell it out letter-by-letter in the document language.
If the UA does not know how to pronounce the symbols,
it may handle it as numbers.

For example, lower-greek in English would be read out as "alpha", "beta", "gamma", etc.
Conversely, upper-latin in French would be read out as (in phonetic notation) /a/, /be/, /se/, etc.

The counter’s value is instead spoken out in the specified style
(similar to the behavior of the fallback descriptor when generating representations for a counter value).
If the specified style does not exist,
this value is treated as auto.
If a loop is detected when following speak-as references,
this value is treated as auto
for the counter styles participating in the loop.

The ability to defer pronunciation to another counter style can help when the symbols being used aren’t actually letters.
For example, here’s a possible definition of a circled-lower-latin counter-style, using some special unicode characters:

Setting its system to alphabetic would normally make the UA try to read out the names of the characters,
but in this case that might be something like "Circled Letter A",
which is unlikely to make sense.
Instead, explicitly setting speak-as to lower-latin ensures that they get read out as their corresponding latin letters, as intended.

The symbols() function allows a counter style to be defined inline in a property value,
for when a style is used only once in a stylesheet and defining a full @counter-style rule would be overkill.
It does not provide the full feature-set of the @counter-style rule,
but provides a sufficient subset to still be useful.
The syntax of the symbols() rule is:

The symbols() function defines an anonymous counter style
with no name,
a prefix of "" (empty string)
and suffix of " " (U+0020 SPACE),
a range of auto,
a fallback of decimal,
a negative of "\2D" ("-" hyphen-minus),
a pad of 0 "",
and a speak-as of auto.
The counter style’s algorithm is constructed
by consulting the previous chapter using the provided system —
or symbolic if the system was omitted —
and the provided <string>s and <image>s as the value of the symbols property.
If the system is fixed, the first symbol value is 1.

If a <counter-style-name> is used that does not refer to any existing counter style,
it must act identically to the decimal counter style.

6.
Simple Predefined Counter Styles

The following stylesheet uses the @counter-style rule
to redefine all of the counter styles defined in CSS 2 and CSS 2.1.
This stylesheet is normative—UAs must include it in their UA stylesheet
(or at least act as if these rules were defined at that level).

Alternately, a browser may render these styles using a browser-generated image instead of the defined character.
If so, the image must look similar to the character,
and must be sized to attractively fill a 1em by 1em square.

For the disclosure-open and disclosure-closed counter styles,
the marker must be an image or character suitable for indicating
the open and closed states of a disclosure widget,
such as HTML’s <details> element.
If the image is directional,
it must respond to the writing mode of the element [CSS3-WRITING-MODES],
similar to the bidi-sensitive images feature of the Images 4 module.
For example, the disclosure-closed style might use the characters
U+25B8 BLACK RIGHT-POINTING SMALL TRIANGLE (▸)
and U+25C2 BLACK LEFT-POINTING SMALL TRIANGLE (◂),
while the disclosure-open style might use the character
U+25BE BLACK DOWN-POINTING SMALL TRIANGLE (▾).

7.
Complex Predefined Counter Styles

While authors may define their own counter styles using the @counter-style rule
or rely on the set of predefined counter styles,
a few counter styles are described by rules that are too complex to be captured by the predefined algorithms.
These counter styles are described in this section.

Some of the counter styles specified in this section
have custom algorithms for generating counter values,
but are otherwise identical to a counter style defined via the @counter-style rule.
For example, an author can reference one of these styles in an extends system,
reusing the algorithm but swapping out some of the other descriptors.

All of the counter styles defined in this section have a spoken form of numbers,
and use a negative sign.

7.1.
Longhand East Asian Counter Styles

Chinese, Japanese, and Korean have counter styles
which have a “longhand” nature,
similar to “thirteen thousand one hundred and twenty-three” in English.
Each has both formal and informal variants.
The formal styles are typically used in financial and legal documents,
as their characters are more difficult to alter into each other.

The following table shows examples of these styles, particularly some ways in which they differ.

Because opinions differ on how best to represent numbers 10k or greater
using the longhand CJK styles,
all of the counter styles defined in this section are defined to have a range of -9999 to 9999,
but implementations may support a larger range.
Outside the implementation-supported range,
the fallback is cjk-decimal.

Note: Implementations are encouraged to research and implement counter representations beyond 10k
and report back to the CSS Working Group with data
when a generally-accepted answer is discovered.
Some previous research on this topic is contained in an earlier draft.

The Chinese longhand styles are defined by almost identical algorithms
(specified as a single algorithm here, with the differences called out when relevant),
but use different sets of characters,
as specified by the table following the algorithm.

If the counter value is 0, the representation is the character for 0
specified for the given counter style. Skip the rest of this algorithm.

Initially represent the counter value as a decimal number. For each
digit that is not 0, append the appropriate digit marker to the digit.
The ones digit has no marker.

For the informal styles, if the counter value is between ten and
nineteen, remove the tens digit (leave the digit marker).

Drop any trailing zeros and collapse any remaining zeros into a single
zero digit.

Replace the digits 0-9 with the appropriate character for the given
counter style. Return the resultant string as the representation of the
counter value.

The ethiopic-numeric counter style is defined for all positive non-zero numbers.
The following algorithm converts decimal digits to ethiopic numbers:

If the number is 1,
return "፩" (U+1369).

Split the number into groups of two digits,
starting with the least significant decimal digit.

Index each group sequentially,
starting from the least significant as group number zero.

If the group has the value zero,
or if the group is the most significant one and has the value 1,
or if the group has an odd index (as given in the previous step) and has the value 1,
then remove the digits
(but leave the group, so it still has a separator appended below).

For each remaining digit,
substitute the relevant ethiopic character from the list below.

Tens

Units

Values

Codepoints

Values

Codepoints

10

፲

U+1372

1

፩

U+1369

20

፳

U+1373

2

፪

U+136A

30

፴

U+1374

3

፫

U+136B

40

፵

U+1375

4

፬

U+136C

50

፶

U+1376

5

፭

U+136D

60

፷

U+1377

6

፮

U+136E

70

፸

U+1378

7

፯

U+136F

80

፹

U+1379

8

፰

U+1370

90

፺

U+137A

9

፱

U+1371

For each group with an odd index (as given in the second step),
except groups which originally had a value of zero,
append ፻ U+137B.

For each group with an even index (as given in the second step),
except the group with index 0,
append ፼ U+137C.

Concatenate the groups into one string,
and return it.

For this system, the name is "ethiopic-numeric",
the range is 1 infinite,
the suffix is "/ " (U+002F SOLIDUS followed by a U+0020 SPACE),
and the rest of the descriptors have their initial value.

8.
Additional Predefined Counter Styles

The Internationalization Working Group maintains a large list of predefined @counter-style rules for various world languages
in their Predefined Counter Styles document. [predefined-counter-styles]
These additional counter styles are not intended to be supported by user-agents by default,
but can be used by users or authors copying them directly into style sheets.

The remaining attributes on getting must return a DOMString object
that contains the serialization of the associated descriptor defined for the associated rule.
If the descriptor was not specified in the associated rule,
the attribute must return an empty string.

If the returned value is invalid according to the given descriptor’s grammar,
or would cause the @counter-style rule to become invalid,
do nothing and abort these steps.
(For example, some systems require the symbols descriptor to contain two values.)

If the attribute being set is system,
and the new value would change the algorithm used,
do nothing and abort these steps.
It’s okay to change an aspect of the algorithm,
like the first symbol value of a fixed system.

Set the descriptor to the value.

10.
Sample style sheet for HTML

This section is informative, not normative.
HTML itself defines the styles that apply to its elements,
and in some cases defers to the user agent’s discretion.

Special thanks to Xidorn Quan for extensive reviews of all aspects of the spec.

Conformance

Document conventions

Conformance requirements are expressed with a combination of
descriptive assertions and RFC 2119 terminology. The key words "MUST",
"MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT",
"RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this
document are to be interpreted as described in RFC 2119.
However, for readability, these words do not appear in all uppercase
letters in this specification.

All of the text of this specification is normative except sections
explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words "for example"
or are set apart from the normative text with class="example",
like this:

This is an example of an informative example.

Informative notes begin with the word "Note" and are set apart from the
normative text with class="note", like this:

Note, this is an informative note.

Advisements are normative sections styled to evoke special attention and are
set apart from other normative text with <strong class="advisement">, like
this:
UAs MUST provide an accessible alternative.

Conformance classes

Conformance to this specification
is defined for three conformance classes:

A style sheet is conformant to this specification
if all of its statements that use syntax defined in this module are valid
according to the generic CSS grammar and the individual grammars of each
feature defined in this module.

A renderer is conformant to this specification
if, in addition to interpreting the style sheet as defined by the
appropriate specifications, it supports all the features defined
by this specification by parsing them correctly
and rendering the document accordingly. However, the inability of a
UA to correctly render a document due to limitations of the device
does not make the UA non-conformant. (For example, a UA is not
required to render color on a monochrome monitor.)

An authoring tool is conformant to this specification
if it writes style sheets that are syntactically correct according to the
generic CSS grammar and the individual grammars of each feature in
this module, and meet all other conformance requirements of style sheets
as described in this module.

Partial implementations

So that authors can exploit the forward-compatible parsing rules to
assign fallback values, CSS renderers must
treat as invalid (and ignore
as appropriate) any at-rules, properties, property values, keywords,
and other syntactic constructs for which they have no usable level of
support. In particular, user agents must not selectively
ignore unsupported component values and honor supported values in a single
multi-value property declaration: if any value is considered invalid
(as unsupported values must be), CSS requires that the entire declaration
be ignored.

Experimental implementations

To avoid clashes with future CSS features, the CSS2.1 specification
reserves a prefixed
syntax for proprietary and experimental extensions to CSS.

Prior to a specification reaching the Candidate Recommendation stage
in the W3C process, all implementations of a CSS feature are considered
experimental. The CSS Working Group recommends that implementations
use a vendor-prefixed syntax for such features, including those in
W3C Working Drafts. This avoids incompatibilities with future changes
in the draft.

Non-experimental implementations

Once a specification reaches the Candidate Recommendation stage,
non-experimental implementations are possible, and implementors should
release an unprefixed implementation of any CR-level feature they
can demonstrate to be correctly implemented according to spec.

To establish and maintain the interoperability of CSS across
implementations, the CSS Working Group requests that non-experimental
CSS renderers submit an implementation report (and, if necessary, the
testcases used for that implementation report) to the W3C before
releasing an unprefixed implementation of any CSS features. Testcases
submitted to W3C are subject to review and correction by the CSS
Working Group.

CR exit criteria

For this specification to be advanced to Proposed Recommendation,
there must be at least two independent, interoperable implementations
of each feature. Each feature may be implemented by a different set of
products, there is no requirement that all features be implemented by
a single product. For the purposes of this criterion, we define the
following terms:

independent

each implementation must be developed by a
different party and cannot share, reuse, or derive from code
used by another qualifying implementation. Sections of code that
have no bearing on the implementation of this specification are
exempt from this requirement.

interoperable

passing the respective test case(s) in the
official CSS test suite, or, if the implementation is not a Web
browser, an equivalent test. Every relevant test in the test
suite should have an equivalent test created if such a user
agent (UA) is to be used to claim interoperability. In addition
if such a UA is to be used to claim interoperability, then there
must one or more additional UAs which can also pass those
equivalent tests in the same way for the purpose of
interoperability. The equivalent tests must be made publicly
available for the purposes of peer review.

implementation

a user agent which:

implements the specification.

is available to the general public. The implementation may
be a shipping product or other publicly available version
(i.e., beta version, preview release, or "nightly build").
Non-shipping product releases must have implemented the
feature(s) for a period of at least one month in order to
demonstrate stability.

is not experimental (i.e., a version specifically designed
to pass the test suite and is not intended for normal usage
going forward).

The specification will remain Candidate Recommendation for at least
six months.