Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does "canonical order" mean with respect to CSS properties?

MDN's pages about CSS properties (example) and some of the CSSWG's specifications (example) make reference to the "canonical order" of the property.

For example, MDN says the canonical order of display is:

the unique non-ambiguous order defined by the formal grammar

and the CSSWG's flexbox spec says the canonical order of flex is:

per grammar

Every CSS property seems to be listed on MDN as having a canonical order; canonical order is also mentioned in the entertaining CSS Foo Module Level N specification that CSSWG uses as a template for new property specifications.

What does this mean, and where is the meaning specified (if anywhere)? I haven't managed to track down a definition of the term online, nor can I think of any obvious guesses.

like image 650
Mark Amery Avatar asked Mar 10 '15 12:03

Mark Amery


1 Answers

The grammar of a property refers to the syntax for a value of said property in a CSS declaration. Most properties take a single value, but some properties take multiple values in set orders, for example box-shadow and background-repeat, as well as shorthand properties. This grammar is usually seen directly in the "Value:" line but may be elaborated in the prose, for example if the property takes a comma-separated list of such complex values.

For example, the grammar of the level 3 background shorthand is defined as zero or more <bg-layer>s followed by one <final-bg-layer>, where

<bg-layer> = <bg-image> || <position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box> || <box>
<final-bg-layer> = <bg-image> || <position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box> || <box> || <'background-color'>

The two <box> values are described as follows:

If one <box> value is present then it sets both ‘background-origin’ and ‘background-clip’ to that value. If two values are present, then the first sets ‘background-origin’ and the second ‘background-clip’.

And the || delimiters between each component mean that one or more of those components can occur and in any order. In the case of background, notice that background-position and background-size do not have a || between them; this means the two properties need to appear together (and for background-size to be specified, background-position must be included).

For example, the following two declarations are valid and equivalent:

background: url(see-through.png) center / 100% no-repeat fixed padding-box red;
background: red url(see-through.png) fixed padding-box no-repeat center / 100%;

No specification appears to define the term "canonical order", but CSSOM makes a number of references to it in the context of serialization. For instance, in section 5.4.3 it says:

The specified order for declarations is the same as specified, but with shorthand properties expanded into their longhand properties, in canonical order.

The values of these longhands are serialized for the purposes of getPropertyValue(), setProperty(), setPropertyValue() and setPropertyPriority(), all of which refer to the "canonical order" as well.

Not every property has a canonical order, since as mentioned above most properties take only a single value anyway; the "Canonical order:" line is present in the lone propdef table in css-module-bikeshed simply because it's a template. Furthermore, CSSOM seems to imply that only shorthand properties have a canonical order.

Based on my understanding of the relevant specifications, when the canonical order of a shorthand property is defined as the grammar of that value, it simply means that its longhands should be serialized in the order that is defined by the grammar. So the above two shorthand declarations should be serialized in the exact same order as the following set of longhand declarations:

background-image: url(see-through.png);
background-position: center;
background-size: 100%;
background-repeat: no-repeat;
background-attachment: fixed;
background-origin: padding-box;
background-clip: padding-box;
background-color: red;

(On an interesting note, the shorthand-to-longhand mapping examples given in the Backgrounds module do not appear to follow this order.)

like image 87
BoltClock Avatar answered Nov 08 '22 20:11

BoltClock