MadLittleMods / postcss-css-variables

PostCSS plugin to transform CSS Custom Properties(CSS variables) syntax into a static representation
https://madlittlemods.github.io/postcss-css-variables/playground/
Other
536 stars 62 forks source link

The substituted value 'undefined' when custom property is undefined #8

Closed bangseongbeom closed 9 years ago

bangseongbeom commented 9 years ago

When a property is undefined(or can not detect for polyfilling... anyway), substituting to 'undefined' is danger. The specification says that the initial value of a custom property is an empty value, but it would be better to leave it just, not to polyfill or substitute.

Input:

.a {
    color: var(--i-am-undefined-property);
}

Output:

.a {
    color: undefined;
}

Expectation:

.a {
    color: var(--i-am-undefined-property);
}
MadLittleMods commented 9 years ago

Discussed in #3.

It seems like current behaviour will act the same because undefined is an invalid value and will cause the browser to use a inherited version.

I am not exactly sure when the unset value functionality should come into play as mentioned below. My understanding now is that it should be unset if there is nothing to inherit from. But I am not sure how this would benefit anything. If some JS later down the road, adds in some styles then those could potentially be inherited. Having this plugin set unset for the value would be detrimental.

Note:

The initial value of a custom property is an empty value; that is, nothing at all. This initial value has a special interaction with the var() notation, which is explained in the section defining var().

Section 2.1: Custom Property Value Syntax, in CSS Custom Properties for Cascading Variables working draft

A declaration can be invalid at computed-value time if it contains a var() that references a custom property with its initial value, as explained above, or if it uses a valid custom property, but the property value, after substituting its var() functions, is invalid. When this happens, the computed value of the property is 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.

Section 3.1: Invalid Variables, in CSS Custom Properties for Cascading Variables working draft


To substitute a var() in a property’s value:

  1. If the custom property named by the first argument to the var() function is animation-tainted, and the var() function is being used in the animation property or one of its longhands, treat the custom property as having its initial value for the rest of this algorithm.
  2. If the value of the custom property named by the first argument to the var() function is anything but the initial value, replace the var() function by the value of the corresponding custom property.
  3. Otherwise, if the var() function has a fallback value as its second argument, replace the var() function by the fallback value. If there are any var() references in the fallback, substitute them as well.
  4. Otherwise, the property containing the var() function is invalid at computed-value time.

Section 3: Using Cascading Variables: the var() notation, in CSS Custom Properties for Cascading Variables working draft

bangseongbeom commented 9 years ago

Umm... the 'unset problem' is pretty hard. If a browser does not support css custom property then the browser would ignore, else if the browser supports css custom property then the browser would set to unset.

I was mistaken. Instead of color: var(--i-am-undefined-property), it would be good to be substituted to color: unset.

And additionally, 'undefined' is dangerous if a font named 'undefined' really exists.

MadLittleMods commented 9 years ago

I think it is best to leave it to an invalid value so that it falls back properly and I believe will hurt less situations.

Maybe when the major browsers start supporting CSS variables, we can use unset to get true functionality.