- 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