w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.46k stars 658 forks source link

[css-properties-values-api] Are fallbacks provided for registered properties validated by the CP syntax? #10455

Open LeaVerou opened 3 months ago

LeaVerou commented 3 months ago

Take a look at this codepen, which is surprisingly interoperable across UAs: https://codepen.io/leaverou/pen/oNRpEGO

--color is defined as:

@property --color {
    syntax: "lime | yellowgreen";
    initial-value: yellowgreen;
    inherits: false;
}
Actual Expected
image image

Given that…

  1. Registered properties become IACVT when they are given a value that does not parse with their defined syntax,
  2. IACVT properties behave as if their value is unset and properties that do not inherit handle unset as intiial
  3. --color’s initial value is yellowgreen
  4. --color is defined to not inherit

…I would have expected yellowgreen, not transparent. It is especially weird that this only happens when a fallback value is provided that does not match the property syntax.

Given the behavior is interoperable, @kizu assumed there must be a WPT test about this, but could not find a test that would test this interaction. The only place he found that tests the fallback not applying when the variable uses its fallback value is here: https://github.com/web-platform-tests/wpt/blob/master/css/css-pseudo/highlight-cascade/highlight-cascade-003.html#L8-L14 But there is no test (or we can't find it) that covers this weird behavior.

I guess, if anything describes what should happen, then it is https://drafts.csswg.org/css-variables/#invalid-variables

Either the property’s inherited value or its initial value depending on whether the property is inherited or not, respectively, as if the property’s value had been specified as the unset keyword.

However, that is not what is happening in the second test. Changing whether the property inherits and setting --color: lime on the parent does not change the outcome of the second test, only the others: https://codepen.io/leaverou/pen/oNRpEGO

It should be clarified in the specs whether the value of the fallback used in the var() should also be validated by the custom property syntax or treated as an unregistered token stream that is validated at the point of usage (I would vote for the latter, but no strong opinion) and what the behavior is in that case.

Also tagging as Agenda+ since @property usage is going to pick up soon now that Firefox has implemented, and authors are soon going to start hitting this.

Thanks to @kizu for his help in tracking this down

Loirooriol commented 3 months ago

gold is provided as a fallback in a declaration for background, not for --color, so validating it against the grammar of --color seems very unexpected to me.

tabatkins commented 3 months ago

Yeah, fallback in var() should be completely unrelated to whatever conditions are imposed on the custom property referenced by the var(). Nothing in any of the specs suggests there should be such an effect; the behavior of the fallback is indeed just "an unregistered token stream that is validated at the point of usage".

andruud commented 3 weeks ago

Nothing in any of the specs suggests there should be such an effect

It's specified here: https://drafts.css-houdini.org/css-properties-values-api-1/#fallbacks-in-var-references

See also https://github.com/w3c/css-houdini-drafts/issues/360.


But I agree that this seems odd now that we have other arbitrary substitution functions that can violate the "grammar" in the fallback, e.g.:

width: attr(my-width px, auto);
                         ^^^^ <-- Not px, but valid
tabatkins commented 3 weeks ago

Well dang, I'm dumb. But yeah, I think it's better to remove the restriction and let the fallback be anything.

css-meeting-bot commented 3 days ago

The CSS Working Group just discussed [css-properties-values-api] Are fallbacks provided for registered properties validated by the CP syntax?, and agreed to the following:

The full IRC log of that discussion <fantasai> kizu: We have weird behavior which is surprisingly interoperable but not strictly defined
<fantasai> kizu: If we use a registered custom property that validates its value, but use it in a different property, and use var(--foo, fallback) and provide a fallback which is not accepted by this custom property
<fantasai> kizu: the result is ??? in all browsers
<fantasai> s/???/unset/
<fantasai> kizu: basically it is validated by the custom property, not by the property it's applied to
<fantasai> kizu: in the comments Oriol and Tab agree that we should remove this restriction
<emilio> q+
<astearns> ack emilio
<fantasai> fantasai: The fallback should validate against the property, not the custom property
<fantasai> emilio: +1 to removing this restriction. Also need to do more work for fallbacks.
<fantasai> astearns: removing would match the spec?
<fantasai> kizu: no, opposite. Implementations do what nobody expects.
<fantasai> kizu: But not useful.
<fantasai> emilio: Implementations match the spec, just spec is bad.
<fantasai> emilio: don't expect compat risk, we should try to change
<fantasai> PROPOSED: Drop validation of fallbacks wrt their custom property.
<fantasai> RESOLVED: Drop validation of fallbacks wrt their custom property.