[CSS-Variables] Suggestion of change to time of substitution

Currently both the CSS-Variables and CSS-Customs drafts put the time of
substitution of variables / property references at computed-valued time.
I'd like to make the case here for instead substituting at specified-value
time, or even earlier. This applies equally to CSS-Variables and
CSS-Customs (although the case is probably more persuasive with non-custom
property references). For reasons that are probably obvious, I'll be mixing
in things that have already been deferred to L2 or beyond; I hope that's
alright.

The main motivator for this is the 'inherit' keyword. According to the CSS
2.1 spec (the CSS 3 spec defers to 2.1 for the inherit keyword), for a
property with a cascaded value of 'inherit', "[the] computed value from the
parent element becomes both the specified value and the computed value on
the child." This implies that the following snippet
   div {
      var-color: red;
      background-color: blue;
   }
   p {
      var-color: inherit;
      background-color: var(color);
   }
   /////
   <div><p>text</p></div>
produces a paragraph with a red background, not a blue one. This is what I
would expect. However, François gave an example which, with my reading of
the current specification, would not produce the desired results.
Translating it into CSS-Variables syntax, it reads:
   * {
      color: var(text-color, inherit);
    }
The meaning here is clear: if var-text-color is set, use that; if not,
inherit the colour of the containing element. However, an advisory note in
the CSS 2.1 Spec points out that this kind of construction is not allowed:

Note: This implies that, in general, combining these keywords with other
component values in the same declaration results in an invalid declaration.
For example, ‘background: url(corner.png) no-repeat, inherit;’ is invalid.

There are a few different solutions to this, but most of them feel like
kludges to me. As I see it, the specified value should never be "inherit",
and so the UA needs to perform substitutions as (or before) specified
values are computed.
This makes particular sense when thinking about (and I'll switch to
CSS-Customs notation here) the "inherit(...)" function. If this was
substituted after the cascade completed, then "color: inherit;" and "color:
inherit(color);" really would be identical.
It also seems to me that if the specified value of a property will never be
"inherit", neither should it be "var(text-color)". While functions like
calc() only really make sense as computed values, I would argue that
"var()" is not really a function in the usual sense, and should not be
treated like one. As a case in point, the arguments to var can be
essentially anything, and while this makes sense in context, it's not the
usual way a well-defined function is specified.

For CSS-Customs + non-custom property references, this suggestion makes it
easier to implement: the property reference can only be to the specified
value, since the computed value has not yet been calculated.

As to the time that the substitution should occur, it could happen during
the cascade, and in some ways this is my preference, but I haven't yet been
able to come up with a sane algorithm for handling this. If done after the
cascade, I believe an algorithm like François' will work.

I hope this gets serious consideration; I know I'm new here, and this would
be a potentially major change to CSS, but I think that it would be worth
it. On the other hand, if I'm just talking rubbish don't hesitate to rip
this suggestion apart.  :o)

Thanks a lot,
Tom

Received on Wednesday, 31 October 2012 01:23:15 UTC