Re: CSS Variables Draft Proposal

On 2/14/11 4:53 PM, Tab Atkins Jr. wrote:
>>> Do you just let this case fall down a
>>> slow path, where you effectively reparse the block?
>>
>> No; this case simply doesn't arise right now.  You're introducing it, by
>> requiring some sort of non-parse-time discarding behavior.
>
> What about a case like this:
>
> <style>
> p {
>    color: red;
>    color: blue;
> }
> </style>
> <script>
> /* use the CSSOM to change the value of the
>     second 'color' property to '12px'

There is no "second 'color' property" there in Gecko.  Try putting this:

   alert(document.styleSheets[0].cssRules[0].style.length);

in that <script> tag.  It alerts 1 in both Gecko and Presto.  Seems to 
alert 2 in Safari 5, but 1 in Chrome 10 dev.  I don't have IE on hand to 
test right this second.

> Do you drop the first color declaration at parse time

Yes.

> so that the above would leave the block with *no* valid 'color' declarations?

Attempting to set a property via the CSSOM in Gecko just parses the new 
value.  If the value is valid, it's stored in the declaration data 
structure.  If it's not, it's dropped.  Hence you _can't_ set a property 
to an invalid value via the CSSOM in Gecko.

So in the case above, if you do:

   document.styleSheets[0].cssRules[0].style.color = "12px";

you get a nice warning in the error console about a CSS parse error and 
the value of 'color' in document.styleSheets[0].cssRules[0].style 
remains "blue".

Also note that the CSSOM doesn't allow "changing the second 'color' 
property".  It allows changing the 'color' property, period. 
Effectively, a declaration in the CSSOM is treated as a simple map of 
property name to value.

>>>>> 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 how to answer your question, because I'm not entirely
> sure what you mean by "its @vars do not".

The text quoted above clearly says that variables created within the 
div-scoped stylesheet are only available within that one stylesheet, right?

> The third use, in the p's child scoped stylesheet, doesn't have it's
> own $foo definition, and can't use the div's child scoped stylesheet's
> definition, since it's in a private scope, so it uses the global
> definition.  Thus, the background-color is blue.

Right, that's what I thought the spec says.  I'm just saying that this 
seems wrong to me.  For example in this testcase:

<style>
   p { color: red; }
</style>
<div>
   <style scoped>
     p { color: green }
   </style>
   <p>text text text</p>
</div>

The color would be green.  So the normal rules from the div-scoped sheet 
apply to the <p>.  Why shouldn't the @var rules?

> I checked with Hixie before I sent my last email to verify that I was
> saying this correctly.

I think we agree on what you're _saying_; we just disagreee on the 
"correct" behavior.

>> It can still cause problems even so (esp. if multiple scripts interact, one
>> of which writes it and one of which wants to mess with your new APIs).
>
> Oh, of course.  But those aren't legacy constraints, they're problems
> going forward and can be fixed by the author as they come up.

Problems of badly-interacting libraries can be hard to fix.  If we have 
to take the compat and author pain, we have to.  But we should be trying 
to minimize it, not wave it away.

>>> I'd also like there to be a window.css which forwards to
>>> window.document.css, for ease of use.
>>
>> That seems to have even more scope for problems.
>
> The scope is larger, but the problems are the same.

Yes, just more hundreds of thousands of authors that end up cursing your 
name for coming up with the daft idea and then have to spend millions of 
man-hours to fix the resulting problems.  ;)

Again, see above about minimizing pain.

>> So a question.... apart from the handling of !important, how is this
>> different from the override sheet stuff CSSOM specifies already?
>
> Where is the override sheet defined?

Hmm.  It looks like the existing APIs just define ways of doing 
per-element declarations, not an entire stylesheet object.

See http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-DocumentCSS fwiw.

>> That doesn't answer my question.  Consider this style:
>>
>>   div { color: red; color: $foo; }
>>   p { color: $foo; }
>>
>> What is the specified value of "color" for<div>s?  What is the computed
>> value of "color" for<p>s?  How do I reconcile those answers with the text
>> quoted above?
>
> Specified value for each is "$foo".  Computed value for each is
> whatever $foo resolves to, if it's defined and valid.  If not, it's
> "$foo".

Uh...  That doesn't match what you said earlier.  If I have that style and:

   <div>This text is red</div>

and there is no variable named "foo" the text should be red, right?  So 
the computed value for <div> better be "red".  Or am I once again 
missing something?

>> A followup: what happens if you try to change to an unknown type?
>
> The same thing we'd do for setting a value that doesn't agree with the
> type.  Either ignore it or throw an exception or something similar
> that we decide on.

OK.  Point being, this needs to be decided.  I hope you're keeping a 
list of those things, right?

>>   Let's try a more interesting
>> testcase:
>>
>>   @var color $foo red;
>>   * { font-family $foo; }
>>
>> If I have a font with a family name of "red" on my system, will I get it?
>
> I think no.  If a variable is given a type, it must be used as the
> type commands.

That migh be tough.  Gecko, for example, has no concept of "type" in the 
CSS parser, other than on the "type of the token" level.  And the "red" 
token there is definitely and IDENT token, which is perfectly valid for 
font-family.

> I'm not wedded to this answer, if it turns out bad.  It's possible
> that all we do with the type is expose CSSOM interfaces, but otherwise
> typed variables are the same as untyped, and you can use them in
> anything that would accept that value.

I'd be interested in what other implementors think (and that includes 
dbaron, who's a lot more of an expert on this stuff in Gecko than I am).

>> The problem is that by the time we decide it doesn't work the damage will
>> have been done: we'll have interfaces we can't drop for compat reasons but
>> that will sort of suck in actual use.  See getComputedStyle as it is
>> currently practiced.
>
> We should be able to figure out whether or not this sucks during the
> spec/experimental implementation stage, before it reaches the point
> where compat becomes an issue.

I'm glad you're an optimist.  ;)

-Boris

Received on Monday, 14 February 2011 22:28:32 UTC