W3C home > Mailing lists > Public > www-style@w3.org > February 2013

Re: [css-variables] Last call comments

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Sat, 9 Feb 2013 10:22:38 -0700
Message-ID: <CAAWBYDC_UKVQDWTDi2ug1YjjKUmgwxufZxd3Ck8xtWDbRwWCCQ@mail.gmail.com>
To: François REMY <francois.remy.dev@outlook.com>
Cc: CSS WG <www-style@w3.org>
On Fri, Feb 8, 2013 at 4:40 AM, François REMY
<francois.remy.dev@outlook.com> wrote:
> 1] Absence of CSS Reference concept
> While the concept of reference has been present for a while in my own fork
> of the spec, I guess it wasn’t really understood by lack of the explicit
> use-cases I was trying to solve. Let’s try to fix that. The problem I’m
> trying to solve is the interaction between different reference types.
> Consider the following case:
>
>     a[href] {
>         my-href: attr(href); // resolved when used
>     }
>
>     a > div.tooltip::before {
>         content: get(my-href);
>     }

Please use the spec's syntax unless your issue is specifically about a
requested change to the syntax.  Otherwise it's just courting
confusion.  The above code in spec syntax:

a[href] {
  var-href: attr(href);
}

a > div.tooltip::before {
  content: var(href);
}

> This won’t work as the attr() reference won’t be resolved on the anchor but
> on the div, which lacks any href attribute. The problem is that the
> attribute and the property references don’t interact properly. This is why I
> want to define a broader syntax that will give references much more
> expressive power over time.
>
>    a[href] {
>         my-href: get(attr href); // resolved when computed
>    }
>
>    a > div.tooltip::before {
>         content: get(my-href);
>    }

I support some way to eagerly force evaluation at variable-definition
time, so that you can do things like this.  I'm also fine with waiting
for level 2.  (You just need to supply some kind of typing information
so we know how to evaluate the tokens, but exactly how to do so is a
fairly interesting and involved topic.  I tried to add typing to
variables early on, but there were a lot of questions, and we
ultimately dropped it for simplicity and generality.)

> The second important thing about reference is that it make sure we can use
> attribute references as a fallback for property references and vice-versa by
> creating an abstraction level behind all kind of references, and creating a
> framework for other kinds of referencable content (counters, document
> properties, string-sets, ...).
>
> For example, the next level of CSS References could include new features
> like choosing the context in which a reference is resolved, and making that
> change allow to use it for any of the already-defined reference types:
> get(parent attr data-abc), get(shadow-host attr data-mode), ...
>
> Concrete proposals:
> - Refactor the reference resolution algorithm into a reusable wording for
> other references types to come (divide CSS Variables into CSS References +
> CSS Custom Properties).
>
> - Remove the attr() function from CSS Value and Units (that section will
> keep the spec from going to CR, so I guess it’s a good idea anyway) and move
> it to the CSS References spec (and define there both the
> resolution-time-replaced get(attr ...) and the used-value-time-replaced
> attr(...)).
>
> - Define both an used-value-time replaced prop(my-...) and a
> resolution-time-replaced get(prop my-...) in the CSS Property References
> specification.
>
> - Delay the other features Brian & I proposed to CSS References L2.

I would prefer to do none of these at this level.  The extra
complexity gains us nothing for now (until we add the rest of your
requested stuff), the requested features require significant
discussion and implementation experience, and the current syntax does
not block us from doing things similar to what you want in the future.

Also, attr() won't prevent V&U from going to CR, since it's already in CR. ^_^


> 2] Inextensibility to all properties
> I don’t see any reason why we could not reference the cascaded value of any
> property inside another, and not just custom properties as it’s now.
>
> (Please note I’m not speaking about computed or used value here, because
> those values aren’t accessible at computation time anyway). Here’s a
> concrete use-case currently solved neither by CSS Variables in preprocessors
> nor by [css-variables] as it’s defined now:
>
>     .box {
>         width: 100px;
>         min-height: get(width / 3);
>     }
>
>     .large {
>          width: 200px;
>     }
>
>     .very.large {
>          width: 300px;
>     }
>
> The limitation of cascade-time property values is that you can’t use values
> that depends on the context (like %age in some cases, or auto) but as an
> author I believe you can understand this (and this is how variables work in
> preprocessors anway!).
>
> The benefits in term of expressiveness are huge. Using a custom property in
> that case would be a waste (think about namespace pollution if you have
> multiple boxes nested, you nead a lot of rules to clean the state at each
> level and prevent leaks).
>
> Concrete proposals:
> - Replace var(name) by get(var-name)/get(prop var-name) and prop(var-name)
> to make referencing any property syntaxically possible and delay to CSS
> Custom Properties L2 the ability to actually reference non-custom properties
> at cascaded-value time (to make sure the L1 goes CR as soon as possible),
> for L1 specify that referencing a non-custom property is invalid at
> computation time.

Using cascaded values is likely confusing, since most authors have
little conception of the value stages in the first place, and the
cascaded value leaves quite a lot of things unresolved.

Also, this can be done with a light refactoring using current
variables.  In your example, replace all instances of 'width' with
'var-width', then add a "width: var(width);" declaration to the first
rule.  While *slightly* less convenient, this is doable with no new
features, and no possibility of confusion wrt value stages.


> 3] ‘Variables’ naming
> I’m not sure it’s still worth mentioning but I’m against the Variables
> wording. The initial spec evolved completely after Roland Steiner proposal
> for custom properties and the old naming was conserved even if, actually,
> the content of the spec changed completely.
>
> I’ve a few slides explaining the difference I see between Variables and
> Properties and why they’ll coexist, it’s faster to read than a whole text
> explaining it all.
>
> http://sdrv.ms/10Ws9dB
>
> I’m fine with the latest name proposed by Daniel, but I still would like to
> get rid of the ‘var’ prefix and the ‘variables’ denomination of the spec;
> the second one being replaced by ‘references’ as explained previously.
>
> For the prefix: choose anything, but not var. Proposals include ‘data’, ‘x’,
> ‘my’, ‘cst’, ‘ext’ and ‘author’. If needed, I’m okay to prepare a small
> pro/con for each of those proposals and their origin.
>
> I’m not considering this as yet-another-last-call-rename because no
> widespread implementation is currently in use or largely documented and the
> renaming proposal holds for a long time, this is not a last-minute change of
> mind. I think it’s worth considering if we want to avoid people to
> misunderstand the concept.
>
> Concrete proposals:
> - Get rid of ‘var’ as a custom property prefix.

The current naming is intentional; it's not an accidental artifact
left over from a previous draft.  The concept hasn't changed in any
significant way - all we did was slightly change the syntax for
defining variables (property rather than at-rule), and made them
cascading rather than global.  These changes, while significant, had
no impact on the concepts in the spec.

For most people, the concept will be "variables", so that's the naming
I'm using.

>
>
> 4] Default value syntax and comma-overloading
> I’m also dropping a note on the currently envisioned syntax for default
> values in CSS References. My draft is using || as a separator instead or ,
> because it’s much more readable and it allows to append more new arguments
> (like type converters) to the get()/var() function.
>
>     get(my-property | 3 | px);
>     var(property, 3, px) // ‘, px’ is parsed as part of the default value
> not as a third argument
>
>     get(my-font || font1,font2,sans-serif);
>     var(font, font1,font2,sans-serif); // confusing
>
> Concrete proposals:
> - Get rid of ‘,’ as an argument separator in get()/var(), use “||” or “;”

Comma is a standard separator for arguments in CSS.  We can add more
stuff into the syntax quite easily by just putting it in the first
argument.  The only other separate we use in CSS is /, which can be
used if necessary for disambiguation later.

> PS: By the way, I propose a split-up in two specs of the current one (CSS
> Custom Properties (custom props & object model for javascript use) + CSS
> References (using custom props inside CSS, attribute references, ...) and I
> would not bother the first one to be CR-ized indecently of the second one
> because JavaScript usages of CSS Custom Properties exist independently of a
> way to reuse them in CSS.

There's no reason to separate the two concepts, since they're
necessary to get the full value out of variables anyway.  The spec has
several examples which talk about using custom properties solely for
JS, but if you'd like to write your own tutorials for such, feel free.

~TJ
Received on Saturday, 9 February 2013 17:23:26 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 17:21:05 GMT