Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define canonical order of longhand properties #6894

Closed
cdoublev opened this issue Dec 16, 2021 · 7 comments
Closed

Define canonical order of longhand properties #6894

cdoublev opened this issue Dec 16, 2021 · 7 comments
Labels

Comments

@cdoublev
Copy link
Collaborator

cdoublev commented Dec 16, 2021

The specified order of declarations define that shorthand properties [are] expanded into their longhand properties, in canonical order, and a general principle of serialization is that if certain component values can appear in any order without changing the meaning of the value (a pattern typically represented by a double bar || in the value syntax), reorder the component values to use the canonical order of component values as given in the property definition table.

When setting background to a single <final-bg-layer>, Chrome serializes the component values in the order derived from <bg-layer> and append <bg-color> at the end, while Firefox serializes in another order.

style.background = 'url("bg.jpg") left 10% / 100px 100% no-repeat fixed content-box padding-box red'
console.log(style.background)
// Chrome: same as input
// Firefox: red url("bg.jpg") no-repeat fixed left 10% / 100px 100% content-box padding-box

The motivation of this request is two fold. It would be also handy to be able to extract a list of shorthands from eg. w3c/webref (see #2921). Using this tool, I can extract a list of shorthands by searching for individual or shorthand in the initial or computed value fields, but there are some inconsistencies between specifications and I'm not sure that this method is 100% accurate.

Therefore a new definition field value, eg. shorthand for, would answer both parts of this request.

Related: #5741.

@SebastianZ
Copy link
Contributor

SebastianZ commented Dec 29, 2021

The order in <final-bg-layer> got changed many years ago. For the background of this, please see https://bugzilla.mozilla.org/show_bug.cgi?id=743392 and https://lists.w3.org/Archives/Public/www-style/2015Jan/0406.html.

It seems Chromium's implementation is incorrect as it should follow the canonical order as described in https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-getpropertyvalue. Interestingly, the serialization puts the color value first when working with the computed style.

document.body.style.background = 'url("bg.jpg") left 10% / 100px 100% no-repeat fixed content-box padding-box red'
console.log(getComputedStyle(document.body).background)
// rgb(255, 0, 0) url("bg.jpg") no-repeat fixed 0% 10% / 100px 100% content-box padding-box

That aside, the request to add a shorthand for definition field sounds reasonable to me.

Sebastian

@cdoublev
Copy link
Collaborator Author

Thanks for the links. It's interesting to have these historical details.

So Firefox uses the order defined in the title of the definition of background in CSS2. I think I missed the field canonical order: by grammar , which I think implicitly defines the following order:

Position CSS3 CSS2
1 background-color background-color
2 background-image background-image
3 background-position background-repeat
4 background-size background-attachment
5 background-repeat background-position
6 background-attachment background-size
7 background-origin background-origin
8 background-clip background-clip

I might not have opened this issue otherwise, sorry. But this field could also be defined explicitly to make its interpretation less ambiguous in some cases.

For example, for border, its grammar gives the order border-<side>-width, border-<side>-style, border-<side>-color, but the <side> order is only defined in prose of the corresponding shorthands (border-width, border-style, border-color).

@cdoublev
Copy link
Collaborator Author

cdoublev commented May 31, 2022

Another case where the canonical order is not obvious from reading its grammar: font.

[ [ <'font-style'> || <font-variant-css2> || <'font-weight'> || <font-stretch-css3> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | caption | icon | menu | message-box | small-caption | status-bar

Should font-variant sub-properties appear between font-style and font-weight?

@karlcow
Copy link
Member

karlcow commented Sep 1, 2022

This creates side effects on WPT where for example the 5th test fails because of the order of values after serialization more than the fact of having multiple values for the background.
https://wpt.fyi/results/css/css-backgrounds/parsing/background-shorthand-serialization.html?label=experimental&label=master&aligned

@emilio
Copy link
Collaborator

emilio commented Sep 1, 2022

I think the order is clear in the spec. Chromium / WebKit seem wrong here.

@emilio emilio closed this as completed Sep 1, 2022
@emilio
Copy link
Collaborator

emilio commented Sep 1, 2022

I guess we can keep this open if you want a more structured way to access the order, though? Feel free to reopen if so, though that's probably an editorial issue.

@cdoublev
Copy link
Collaborator Author

cdoublev commented Sep 1, 2022

I think the order is clear in the spec.

I cannot understand how it can be clear from reading the value definition. <bg-layer>, which cannot match a value for background-color, appears before <final-bg-layer>, which can match background-color.

Firefox is consistent and puts background-color first. Chrome puts it last when serializing a specified value but last for a computed value. I would have said it should come last.

Firefox also puts background-repeat and background-attachment before background-position and background-size, whereas the formers appears after the latters in the grammar. This order comes from CSS 2, not CSS 3, as explained to me by Sebastian. Conforming to an older syntax may be required.

The property definition tables already have a Canonical order. It is a different request, but I thought that it is only defined for shorthands, which would have allowed me to extract a list of shorthands from the data extracted by w3c/webref. But it is also defined for all properties, longhands and shorthands, usually with per grammar, like for margin, whose grammar does not allow to define a canonical order, which is not explicitly defined in prose, like for font-variant:

The font-variant property is a shorthand for all font-variant subproperties:

[list in canonical order]

It would be clearer with The font-variant property is a shorthand for all font-variant subproperties defined below in canonical order. You also reported in #5741 that the canonical order of shorthand subproperties does not seem to be clearly defined somewhere.

TLDR: Canonical order could be used to only define the canonical order of shorthand subproperties. This would answer both requests. The canonical order of || and && is always clear to me.

But feel free to keep it closed: I ended up with searching for shorthand in the specs to manually extract a list of shorthands, and browser-interopability seems often very low anyway when it comes to shorthand serialization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants