- From: François REMY <fremycompany_pub@yahoo.fr>
- Date: Mon, 4 Jun 2012 18:36:23 +0200
- To: "CSS 3 W3C Group" <www-style@w3.org>
CSS Variable's syntax has been a very hot topic recently, with no strong majority so far. For the past few days, I really tried to make own all the remarks made by the people I was able to discuss with, and to see how all those (sometimes apparently opposed) point of views could be merged in a single, coherent proposal; I think I kinda succeeded. However, before I jump to anything concrete, I would like to give some context about the main beliefs I’ve been conciliating in the process, and the reasons I chose them. 1. $foo is a popular replacement-initiator token While few languages, to the notable exception of PHP, are actually using the dollar symbol as part of their variable names, it seems that many replacement-based systems are using $ as a magic token introducing a (string) replacement. Samples of this trend include PHP, BASH, REGEXP, XSLT and POWERSHELL. Based on the opinions expressed on this list and on Twitter, it seems that going against that movement is a difficultly sustainable position. Catalysts include habits, consistency with existing programming languages and no breaking change required for the value tokenizer (to the contrary of a 'just use the variable name' approach). 2. People’s expectations of variables won’t meet CSS implementation CSS variables exhibit a behavior fairly distant from any variable implementation to date. Many invariants of traditional variables are not going to be met by CSS variables. Avoiding confusion has thus to be a key criterion in our syntax choice. As people have divergent experiences and knowledge, a good choice should as much as possible rely on the already-existing understanding of the CSS language. Besides being defined the same way as CSS properties, CSS variables are going to behave in a very similar way (regarding inheritance, cascading, scope, and value tokenization). In fact, in the current working draft, they are even defined as traditional CSS properties. This led me in the past go as far as calling them “user-defined properties”. I think this is something to preserve. 3. Learning from HTML: An user-defined property is still a property Just like the HTML data attributes are specification-defined user-reserved attributes having no effect on the document’s rendering and behavior (unlike other HTML attributes), CSS variables aren’t going to have any impact on the page (unlike other CSS properties) unless some user code defines how to perform the mapping between those user-defined properties and the framework-understandable ones. In CSS, this mapping process is likely to happen in two ways: using token replacement in other CSS properties (previously var()), and using client-side scripting (via DOM/CSSOM). In the HTML case, mapping tools are quite similar: CSS' attr() and scripting are likely to be used. 4. Often, prequels are important to understand a story The first recognized use of variable in CSS is often seen as the ‘currentColor’ keyword. This keyword has a very special behavior in the sense it computes to the value of the color property. When creating a dependency circle (color: currentColor), the declaration is treated just like an invalid-at-runtime CSS variable would, and ‘color’ returns to its default state (inherit). This example is interesting for two reasons: because it shows that, quickly, ‘variables’ have shown to be necessary for representing the complexity of page layouts and because it seems that even ‘native’ CSS properties (I call them framework-provided) can be a reference target (more on that later; I just want you to keep this in mind for the moment). Another variable-like use-cases include the ‘em’ unit (which is nothing more than the (computed) value of the ‘font-size’ property) and the newly created ‘align-items’ (which can be understood as a default value for the otherwise not-inherited ‘align’ property). 5. Why we don’t want { $foo: bar } As noted by some users, this syntax is confusing; firstly because authors expect intuitively to be able to use preprocessor variables anywhere, including in selectors and to shorten property names. This means that “$foo: bar” can easily be confused as “the property name contained by the foo variable should be set to bar” instead of “the foo variable should be set to bar”. Secondly, this is breaking the core CSS grammar which has been referenced as non-updatable by this working group several times. Reasons include incompatibility with tools and browsers. “html { $color: red; }” is for example understood as “html { color: red; }” by IE6 and IE7. Compatibility with existing tools is clearly something we should take care. Last but not least, this is hiding the property-like nature of CSS variables, which severely impairs the clarity and discoverability of the feature. 6. Why we need a prefix However, if we don’t use the $ prefix, we have to restrict the names authors can give to their user-defined properties. The reason is pretty clear: a CSS variable should never collide with a future framework-provided property. If variable names are constrained by a prefix, this becomes a no-brainer: future properties won't use that prefix. Based on my reflection, I initially coined the “x-” prefix (whic is a nice and short prefix for user-defined things) but Sylvain noted it’s being deprecated in the HTTP protocol. My current preference goes to a 'my-' prefix; however, a more consensual choice like “data-” is probably seen as more acceptable by the WG members, I don't know. [[Disgress: Actually, it’s to be noted that "data-" was the used prefix before the current draft and made consensus at the time in the CSS WG. However, the data() function led many to think this would be confused with HTML’s data attributes. This function being gone, I think we can remove that fear from our list and benefit from the name semantics. In fact, I think that the similarity of working between HTML’ data attributes and CSS variables can gain to be outlined.]] 7. Variables should be consistent in name Last but not least, many stated on this list that they din't like the fact a variable "changed" of name between the time it's been set and the time it's retreived. Because it makes things much clearer when the name is contant, I wanted to keep it so in my proposal. 8. Sum it all up Here’s finally a sample file based on my syntax proposal: :root { my-link-color: red; } header { my-link-color: white; } a { color: $my-link-color; } I think it takes in consideration all of the seven preceeding points, and is a balanced solution. 9. Things I would like to highlight Here are important things I would like you to note about the proposal: - The $ is not part of the property name: this is a replacement indicator token. This means that it can be reused for any future replacement behavior that may benefit from it: this is very future-proof. - Variables are still properties like any other. In a future revision of the spec, we may allow things like $color (a value semantically equivalent to currentColor). There’s no reason a property could not reference the specified value of another property as long as no dependency circle is created. And we now have a solid resolution to apply in case such a dependency circle happens in practice. 10. Thoughts? Please feel free to comment this proposal; I’m eager to see what you all think of it. Thank you all for reading a so long mail up to the end! François
Received on Monday, 4 June 2012 18:07:01 UTC