- From: Marat Tanalin | tanalin.com <mtanalin@yandex.ru>
- Date: Thu, 24 May 2012 19:44:05 +0400
- To: Christoph Päper <christoph.paeper@crissov.de>
- Cc: www-style list <www-style@w3.org>
IMO, sharing same "namespace" between variables and other syntax constructs is a big mistake that causes unneeded ambiguity, complexity, and confusion. At the contrary, variables in CSS should not be overcomplicated, otherwise it will never be done or at least not in foreseeable future that we (not our grandchildren) will have a chance to touch. CSS speccing process is too slow anyway, we should not make it even slower. What web developers really need ever since CSS was initially invented is to JUST assign some value to a variable and then automatically insert the value to some place where the value itself is used currently. This is quite trivial and can be done in a few months including both speccing and implementing. And this is MUCH more important than some redundant things like special cascading rules, default values, overloading, or anything else that some people for some reason are trying to invent. Simple variables functionality that we could really use reasonably soon are hugely better then some theoretically super-smart/flexible/ideal variables that we will never be able to use. 24.05.2012, 18:54, "Christoph Päper" <christoph.paeper@crissov.de>: > Christoph Päper: > >> I’m still a fan of using variable names verbatim, i.e. no prefix, no function notation, no nothing: > > Proposed Syntax (Example) > ========================= > >> color: foo-bar; >> var_foo-bar: blue; > > color: foo-bar !important; > color: foo-bar !override; > >> if variables were just user-defined keywords we needed to come up with a system that establishes the order of preference so authors either could or could not overload existing and future keywords. > > Usage Scenarios > =============== > > Usually authors will use variable names that are not equivalent with any keyword. Even if they do, said keyword might not be valid where the variable is used, so there’s no ambiguity either. When authors use a keyword for a variable’s name they usually do so by intention. Hardly ever there is a new keyword added to a property later on and very rarely this could result in a clash in existing stylesheets with new browsers that was not foreseen by the author. Even when that happens, in many cases the new official keyword will do something similar to what the author originally intended. > > Proposed Precedence Policy > ========================== > > – Global keywords (‘inherit’, ‘initial’, ‘default’ > are illegal to use as variable names. > (‘normal’, ‘none’ and ‘auto’ probably should be, too.) > > – By default an existing keyword (supported by the UA) > takes precedence over a declared variable. > > – A unit, pseudo-function name or priority marker > can never be overridden by a variable. > > – A user-defined keyword from another source, > e.g. a custom font family from ‘@font-face’, a named page, > a counter or its style from ‘@counter-style’, > can never be overridden by a variable. > > – If the ‘!important’ priority marker is specified > for the declaration, any variable takes precedence, > but if that results in an invalid declaration > it falls back to the pre-defined keyword, > which also may be invalid there, though. > > – If the (new) ‘!override’ priority marker is specified > for the declaration, any variable takes precedence > and possibly invalidates an otherwise valid declaration. > > – Both markers apply to all variables in a declaration, > because per the grammar, only one of the priority markers > (‘!’ followed by either ‘important’ or ‘override’) > can be used at a time and only once per declaration. > > – For matters of the cascade ‘!override’ equals ‘!important’ > (Maybe there needed to be two additional equivalent markers > that had no impact on the cascade whatsoever). > > Frequent Demands > ================ > >>> I need a default value if the variable is invalid where used. > > This is usually not needed, because one would just use an appropriate fallback keyword as the variable’s name. A better solution would be stronger typed and automatically cast variables, e.g. > > length_foo: 20px; > color_foo: blue; > keyword_foo: solid; > complex_foo: 20px length(foo); > border-width: foo; /* = length(foo) */ > border-color: foo; /* = color(foo) */ > border-style: foo; /* = keyword(foo) */ > border: foo; > border-radius: complex(foo); > >>> I want to use the value the variable had in this element’s parent. > > (Why?) > > parent {var_foo: red; color: foo;} /* red */ > this {var_foo: orange; color: foo !inherit;} /* red */ > child {var_foo: green; color: foo;} /* green */ > > or > > parent {var_foo: red; color: foo;} /* red */ > this {var_foo: orange !defer; color: foo;} /* red */ > child {var_foo: green; color: foo;} /* green */ > >>> Variables must be able to contain more and less than one “atomic” value, >>> e.g. a comma-separated list of values or a pseudo-function argument.” > > :root {var_foo: 100;} > bar {color: rgb(foo, foo, foo);} /* valid */ > baz {color: rgb(foo%, foo%, foo%);} /* invalid */ > quz {color: rgb(foo);} /* invalid */ > > :root {var_foo: 100, 50, 25;} > bar {color: rgb(foo);} > > :root {var_rgb: rgba;} > bar {color: rgb(100, 50, 25)} /* valid, no var use */ > bar {color: rgba(100, 50, 25, 0)} /* valid, no var use */ > bar {color: rgb(100, 50, 25, 0)} /* invalid, no var use */ > >>> My variable should cycle through two or more values, advancing one step each time it is used. > > Each variable aligns with a counter of the same name (remember that counter names always take precedence over variable names). The ‘cycle()’ pseudo-function takes as a second parameter the counter it should use and increment by one afterwards. > > :root {var_foo: cycle(red green, foo);} > bar {color: foo; background-color: foo;} /* alternating red-red and green-green */ > baz {counter-increment: foo;} > > :root {var_foo: red; var_bar: green;} > baz {color: cycle(foo bar);} /* anonymous counter for this selector */ > baz {color: cycle(foo bar, foo);} /* explicit existing counter */ > baz {color: cycle(foo bar, quz);} /* explicit new counter */ > >>> What happens if I use variables or priorities inside variable declarations? > > var_foo: 0 !important; /* higher specificity of assignment */ > var_foo: 0 !override; /* same as with ‘!important’ */ > var_foo: bar; /* loses against declarations above */ > > var_bar: baz; > var_foo: bar; /* treated as keyword ‘bar’ */ > var_foo: bar !important; /* almost the same as “var_foo: baz;”, > doesn’t fall back to keyword ‘bar’ */ > var_foo: bar !override; /* almost the same as “var_foo: baz;”, > except when ‘baz’ is not specified */
Received on Thursday, 24 May 2012 15:45:23 UTC