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

[css-cascade][cssom] Define what happens when legacy shorthand has grammar broader than longhand #7195

Open
Loirooriol opened this issue Apr 1, 2022 · 4 comments
Labels

Comments

@Loirooriol
Copy link
Contributor

https://drafts.csswg.org/css-cascade-4/#legacy-shorthand

When the old property has a distinct syntax from the new property, the two names are aliased using the shorthand mechanism. These shorthands are defined to be legacy shorthands, and their use is deprecated. They otherwise behave exactly as regular shorthands, except that the CSSOM will not use them when serializing declarations.

The problem is that some of these legacy shorthands can accept some values which have no equivalent in the standard property. For example, https://drafts.csswg.org/css-backgrounds-3/#propdef-background-clip

<'background-clip'> = <box>#
<box> = border-box | padding-box | content-box

But then https://compat.spec.whatwg.org/#the-webkit-background-clip-property defines this legacy shorthand:

<'-webkit-background-clip'> = border-box | padding-box | content-box | text

So it's not clear what happens if you set -webkit-background-clip: text. I would expect something like:

CSS.supports("-webkit-background-clip: text"); // true
CSS.supports("background-clip: text"); // false
element.style.cssText = "-webkit-background-clip: text";
element.style.length; // 1
element.style[0]; // "background-clip"
element.style.webkitBackgroundClip; // "text"
element.style.backgroundClip; // ""
getComputedStyle(element).webkitBackgroundClip; // "text"
getComputedStyle(element).backgroundClip; // ""

i.e. the shorthand sets the longhand to a special value that cannot be represented by its grammar, so the longhand serializes as empty string, but the shorthand can serialize the value. Somewhat analogous to when setting a shorthand to a variable.

This is what browsers do:

  • Firefox ignores the spec and accepts background-clip: text as valid. This avoids serialization problems:

    CSS.supports("-webkit-background-clip: text"); // true
    CSS.supports("background-clip: text"); // true
    element.style.cssText = "-webkit-background-clip: text";
    element.style.length; // 1
    element.style[0]; // "background-clip"
    element.style.webkitBackgroundClip; // "text"
    element.style.backgroundClip; // "text"
    getComputedStyle(element).webkitBackgroundClip; // "text"
    getComputedStyle(element).backgroundClip; // "text"
  • Blink serializes background-clip as "text", but this seems very wrong because background-clip: text is considered invalid!

    CSS.supports("-webkit-background-clip: text"); // true
    CSS.supports("background-clip: text"); // false
    element.style.cssText = "-webkit-background-clip: text";
    element.style.length; // 1
    element.style[0]; // "background-clip"
    element.style.webkitBackgroundClip; // "text"
    element.style.backgroundClip; // "text"
    getComputedStyle(element).webkitBackgroundClip; // "text"
    getComputedStyle(element).backgroundClip; // "text"
  • WebKit doesn't implement -webkit-background-clip as a shorthand. Instead, it's implemented as an independent longhand that shares a computed style with background-clip (somewhat like physical and logical properties also share a computed value). Additionally, it accepts background-clip: text as valid:

    CSS.supports("-webkit-background-clip: text"); // true
    CSS.supports("background-clip: text"); // true
    element.style.cssText = "-webkit-background-clip: text";
    element.style.length; // 1
    element.style[0]; // "-webkit-background-clip"
    element.style.webkitBackgroundClip; // "text"
    element.style.backgroundClip; // ""
    getComputedStyle(element).webkitBackgroundClip; // "text"
    getComputedStyle(element).backgroundClip; // "text"

Other properties may have other behaviors.

@tabatkins
Copy link
Member

The correct answer here is "mu" - if the legacy shorthand has a value not present in the real longhands, then it's a browser-specific extension. If we want it to not be that, we have to define what that value means in the real property. (Even if the answer is "nothing, this is just a technically-valid legacy keyword that does nothing".)

@Loirooriol
Copy link
Contributor Author

I picked an example which is not a browser-specific extension since supporting -webkit-background-clip: text is required by the Compatibility spec. And its meaning is

Indicates that the background image should clip to the foreground text

@tabatkins
Copy link
Member

Right, so that falls into my second category of "things that need to be in the real spec, even if only as explicitly legacy stuff".

@Loirooriol
Copy link
Contributor Author

Actually, I missed that background-clip: text is already defined in Backgrounds L4.

But I still think the definition of "legacy shorthand" should handle the case of the shorthand having a broader syntax than the longhand.

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

2 participants