Re: CSS Variables Draft Proposal

On 2/9/11 8:22 PM, Tab Atkins Jr. wrote:
> The syntax is `@var`, followed by whitespace, followed by the variable
> name (which must start with a $, and then follow the IDENT
> production), followed by whitespace, followed by an arbitrary series
> of CSS tokens, capped by a semicolon at the end.

The draft on your page now says "component values", which is actually 
worse, since the concept of "component value" is undefined.

In any case, the question of what possible values of a variable are is 
something we really need to pin down before most of the rest of the 
discussion makes sense, because it affects where and how variables can 
be used and hence which use cases they address.

I _think_ you have some personal mental model here, but I don't 
understand what it is, nor how much it's tied to a particular 
implementation.  So can we make it a priority to get this part 
straightened out?  I suspect that once we do a lot of the other 
discussion around variables might need to be revisited.

> Using variables is very easy too - they can be used anywhere you could
> use a component value:

What's a "component value"?   That's not a concept that's present in the 
CSS specs, nor in Gecko's implementation.  Is it something from Webkit's 
implementation?  Something from that mental model of yours?  As I said 
above, the exact definition here affects where variables can actually be 
used.

Note that the desire to have this implementable via a preprocessor (if 
such a desire exists) might affect this; a preprocessor that doesn't 
know anything about the "types" of property values might not do the same 
thing here as what you want to happen... depending on what the heck that 
last is.

The issue of whitespace here has already been brought up, I believe.

> Using a variable that hasn't been declared is a syntax error.  (It's
> valid to use a variable that hasn't been declared *yet* - the
> declaration may appear later in the stylesheet, or in another sheet
> entirely.)

What is the expected behavior of this markup:

div {
   color: red;
   color: $foo;
   color: $bar;
}

in a browser that supports variables if $foo and $bar are both not 
defined?  If $foo then suddenly becomes defined?  If $bar then becomes 
defined?

Currently in a situation like that (same property specified multiple 
times in a declaration) only the last specified value needs to be kept 
by the UA.  It sounds like your proposal is that this is no longer the 
case with variables, right?

> Variables exist in the global scope.  @import'ing a stylesheet makes
> any variables contained within it available to all other sheets.
> Similarly, linking in a stylesheet makes any variables contained
> within it available to all other sheets.

There probably need to be some caveats here about sheets that are not 
applied for various reasons (disabled, not applied due to media queries, 
whatever).  Given that browsers can just not load sheets for media they 
don't support, in theory, the only thing that makes sense to me is that 
if a sheet is not applied then neither are any of its @var rules.

> Scoped stylesheets (those created with a `<style scoped>` element in
> HTML) have their own nested global scope.  Variables created or
> imported within a scoped stylesheet are only available within the
> scoped stylesheet; variables created in the outer global scope are
> still available in a scoped stylesheet.

I'm not sure I follow this.  Say I have this markup:

   <div>
     <p>
     </p>
   </div>

with stylesheets scoped to the <div> and <p>.  If I have an @var in the 
div-scoped sheet, can the p-scoped sheet use it?  Note that rules in the 
div-scoped sheet apply to the <p> and all, in general.

> Variables declared in an @media block are only available if the media
> declaration is true.

Assuming that's even allowed; does the core grammar allow nested @-rules 
now?

> Multiple Variable Declarations
>
> If the same variable name is declared in multiple @var rules, the last
> valid declaration wins.  For this purpose, UA-defined variables come
> before all author-defined rules, which come before all user-defined
> rules.  Within each category, the ordering is document order.  (This
> is intentionally identical to normal CSS precedence rules

Except it's not; it has user and author in the opposite order.  Within 
the set of author sheets the order does match, I agree.

> Changes to CSS Grammar
> ----------------------
>
> To be completed with boring details.

This needs to happen to understand how variables can actually be used; 
see above;

> For use by normal authors, I'll be proposing a new global object on
> `document` named `css`.

Do we have any data on how web-compatible this is?  Also, you just mean 
a property on Document objects, right?  Not a global object in the ES 
sense or anything?  I'm not sure what "global" is supposed to mean there.

What about scoped style sheets?  I guess those can walk the sheet 
directly...

> Changing the value of a map entry changes the underlying value in the
> stylesheet for the declaration being used to produce that value.

What if the setter is called with a string that can't be parsed as a 
variable value (whatever that might mean)?

> To add a new map entry, we first define `css.stylesheet`, which
> implements the `StyleSheet` interface.  This stylesheet is treated as
> an author-level sheet placed after all other author-level sheets.
> Creating a new map entry creates a corresponding @var rule in this
> stylesheet.

What about adding other rules to the sheet?  Would they be applied to 
the document?

> (Should this exist in `document.stylesheets`?

If it's going to apply to the document, then yes.

> Serializing Variables

> Variables appear as themselves in specified values. If the variable is defined and valid, its computed value is the value of the variable. If not, its computed value is the variable name.

I don't understand this at all, if invalid values are supposed to be 
treated like parse errors....  What is this trying to say?

> (The definition of a 'type' is intentionally somewhat loose right now.
>   At minimum, every primitive value is a type, as is every property.
> We may also want some complex component types, like<position>.)

Fwiw, on your webpage you forgot to escape the <> there.

I'm not sure what "primitive" value means here.  Do you mean the kinds 
of values defined by http://www.w3.org/TR/css3-values/#values or 
something else?

> ### Optional Typing ###
>
> Optional typing is just an amendment to the declaration syntax that
> allows the author to specify the variable's type directly.  It would
> look like this:
>
> ~~~~
> @var color $foo red;
> ~~~~

Some obvious questions:

1)  What should a UA do with an unknown type?  Is the @var rule still 
created, for example?  More on this below.

2)  Can the type be changed via the CSSOM?  I assume yes, to make Daniel 
happy.  ;)

2)  If I have this CSS:

   @var color $foo 12px;
   * { font-size: $foo; }

then do I get 12px font-size?  Or is the variable considered invalid if 
its value in the @var can't be parsed as its type?

> ### Late Typing ###
>
> The previous suggestion seems to put the typing in the wrong place.
> Typing doesn't help the CSS developer in any way, as CSS can figure
> out types as necessary all by itself.

Maybe... and maybe not.  It sort of depends on what variable values 
"are".  See beginning of this mail.

> This would only work if the OM interfaces were carefully designed in
> such a way that there is never ambiguity

Seems fragile....

-Boris

Received on Saturday, 12 February 2011 03:42:26 UTC