
CSS Variables land in WebKit - cleverjake
http://trac.webkit.org/changeset/120154
======
underwater
My issue with the spec the W3C settled on is that it contains nuances that
mean it _must_ be implemented in the browser. It is not possible to write a
serverside preprocessor that implements the spec.

Unlike other technologies like canvas or AJAX where we've been able to create
polyfills for older browsers, authors will now have to make an explicit
decision between either using CSS variables or supporting all browsers.

~~~
wccrawford
Can you give some examples of things that can't be done by a preprocessor?

~~~
JoshTriplett
Variable values can cascade like other CSS properties. So, you could define a
theme via a set of variables, and redefine those variables in a CSS class
("selected items look like this"), or a media query ("mobile uses this
theme"), or via JavaScript. That requires evaluation in the browser.

~~~
superk
Preprocessors evaluate CSS and the cascade so there's nothing stopping them
from adding local scope or specificity to variables. On the other hand, if you
can really edit variable values with Javascript then that would be client-side
only, although I haven't seen anything that says you _can_ do that - for all
we know Javascript may only allow getting/setting of the evaluated value, not
the variable expression itself.

~~~
JoshTriplett
> Preprocessors evaluate CSS and the cascade so there's nothing stopping them
> from adding local scope or specificity to variables.

That cascade depends on the structure of the document, not just the CSS. For
instance, consider the following (contrived) example:

    
    
        :root { var-accent: black; }
        .someclass > :first-child { var-accent: blue; }
        .otherclass { background-color: var(accent); }
        .anotherclass :first-letter { color: var(accent); }
    

The value of var(accent) for any element depends on whether the ancestors of
that element include the first child of an element with class="someclass". For
a preprocessor to duplicate that effect on the server side, it would need to
construct all possible combinations of the selectors for the variables and the
selectors depending on those variables:

    
    
        .otherclass { background-color: black; }
        .anotherclass :first-letter { color: black; }
        .someclass > :first-child .otherclass { background-color: blue; }
        .someclass > :first-child .anotherclass :first-letter { color: blue; }
    

Now consider that with a dozen variables and a hundred variable-dependent
rules.

> On the other hand, if you can really edit variable values with Javascript
> then that would be client-side only, although I haven't seen anything that
> says you _can_ do that - for all we know Javascript may only allow
> getting/setting of the evaluated value, not the variable expression itself.

The CSS Variables spec talks about dynamic variable updates via scripting.

------
dcolgan
I recently discovered Less (<http://lesscss.org/>), a CSS preprocessor that
adds support for variables and many other features, like nested rules and
mixins.

Using Less has been one of the most profound upgrades in my use of programming
techniques in quite a while. Hopefully browsers will eventually support even
more Less-like features.

~~~
culturestate
If you like Less, you should try Sass/SCSS (<http://sass-lang.com/>) - same
idea, but a little more powerful. Here's a good head-to-head: <http://css-
tricks.com/sass-vs-less/>

~~~
hackinthebochs
I look a look at the sass-vs-less link, and I really don't see the draw of
either. I don't want a turing-complete language in my css. Simple variable
expansion will suffice--basically just syntactic sugar. I don't want yet
another game of "find the definition" buried under a hierarchy of indirection.
Perhaps its a lack of imagination on my part, but I can't think of a good use
of this power _for the purposes of styling a document_.

~~~
batista
> _I look a look at the sass-vs-less link, and I really don't see the draw of
> either._

Don't look at them, use then, and you'll see.

> _I don't want a turing-complete language in my css. Simple variable
> expansion will suffice--basically just syntactic sugar._

And they are mostly that --simple variable expansion. But arithmetic is also
handy, e.g

.sidebar { width: @page_width - @content_width }

That said, they are not turing-complete as far as I know.

> _I don't want yet another game of "find the definition" buried under a
> hierarchy of indirection._

You never get that. You only have to look at the LESS or SASS file, never the
generated CSS.

And you can mentally map what you see in the browser's CSS inspector with the
relevant LESS/SASS rule trivially.

It's nothing like Coffeescript in this regard, where you (sometimes) have to
hunt to see the original error.

~~~
hackinthebochs
I appreciate the response. I'll have to give them an honest try before making
a judgement.

------
chao-
I would welcome this if I hadn't finally just gotten on board the SASS train.
All I see this doing (for some ill-defined span known as "the present"), is
adding another layer of headache into the browser compatibility game.
Furthermore, I agree with VMG that there's something to be desired in the
chosen syntax.

~~~
ch0wn
There's more to it than what Sass, Less and co. can provide. It simplifies
dynamically changing a bunch of CSS properties from JavaScript a lot. Instead
of changing all the elements using a particular style, you could now change
just the variable instead. This gets even more interesting when properties are
composed of variables, like gradient colors.

Also, this is a pretty high-level addition. I wouldn't be surprised if someone
came up with a polyfill for this soon.

~~~
chao-
That's the biggest draw that I currently see. I would love to reference other
features that SASS and LESS still bring to the table, but the idea of
JavaScript fiddling with CSS variables is mouth-watering indeed.

------
VMG
from <http://www.w3.org/TR/css-variables/>

    
    
        :root {
          var-header-color: #06c;
        }
        
        h1 { background-color: var(header-color); }
    

looks slightly hacky, but better than nothing at all I suppose...

~~~
TabAtkins
Syntax isn't frozen. Here's another possibility:

:root { $header-color: #06c; } h1 { background-color: $header-color; }

(Note that the spec's use of the :root pseudo is just to generically declare
"global" variables that should apply to the whole page. If you're just using
HTML, feel free to use "html" or "body" as the selector instead.)

~~~
nilliams
This syntax is clearly preferable, but I think you knew that or you wouldn't
have written it :)

I'm guessing the justification for the existence of the awkward _var(varname)_
version is so that you can also have the _parent-var(varname)_ notation.

I do think it's interesting how variables are scoped to dom nodes. Is there
any reason it cannot be optional though, so if you omit it, it defaults to
global?

$header-color: #06c; h1 { background-color: $header-color; }

I'm guessing the argument against, is that this requires too much of a change
to CSS parsers, as it doesn't follow the standard form of <selector> {
<properties> }. If that's really the reason it seems a bit of a shame though
:/

~~~
bkardell
I disagree that it is preferable, but that is debatable. I say that in part
for the reasons you mention, but also because it seems to me that quite a lot
of people think that "$header-color" means "substitute the value of the
header-color variable here" regardless of which side it is on. I think there
is probably a happy middle ground where you achieve all of the goodness (looks
like CSS, follows existing core grammar, shows the property nature, uses $ in
familiar ways, etc). Not sure what it is, but probably something like:

:root{ def-primarycolor: blue; }

.x{ background-color: $primarycolor; }

------
bkardell
CSS variables do something fundamentally different than SASS/LESS approaches.
Moreover, it is something which those approaches are incapable of doing.
Conversely, SASS and LESS do something that CSS can never do - be processed
only once.

Much of the confusion I think is in the fact that we are referring to two
dramatically different things by the same word "variables". In CSS terms it is
more helpful (IMO) to think of them more like "user defined properties" which
work exactly like every other property in CSS.

~~~
thechangelog
Or call what SASS and LESS do global constants.

~~~
bkardell
Yes, I agree, but too late for that change probably. Plus I'm sure someone
will point out that they are not actually necessarily constant by strict
definition either. An easier way to think about it is that they are
essentially clever compile time template systems which output CSS... It's
totally unrelated that their input also happens to look a lot like CSS - it
isn't.

------
bendemott
Honestly, it seems the server-side solutions for css meta-syntax that supports
variables are still more suited for this type of thing (such as SASS).

------
dhx
An interesting feature is dynamic updating of dependent variable properties:

    
    
      This example shows a variable property safely using a variable:
      
      :root {
      	var-main-color: #c06;
      	var-accent-background: linear-gradient(to top, var(main-color), white);
      }
      
      The ‘var-accent-background’ property will automatically
      update when the ‘var-main-color’ property is changed.
    

edit: clarified the wording of this comment to remove ambiguity (not a
question).

~~~
monkeyfacebag
Trivially, the difference is that neither SASS nor LESS is actually CSS and
therefore must be transformed into valid CSS prior to being parsed by the
browser. This would eliminate that step.

EDIT: parent originally asked about the difference between this and SASS/LESS.

------
Tichy
I really worry about the future of CSS. It already is the most difficult of
all web techniques to use. Once they introduce the css scripting thing all
bets are off...

------
nthitz
Any idea on when we can expect to see this implemented in Chrome or Safari?

~~~
cleverjake
within a couple days on chrome canary. It was in r120154, and the current OS X
canary is at r120017. That little of a difference usually means a couple days
at most.

Safari on the other hand...probably a year or so. Possibly what comes after
mountain lion. They won't add it in until it is fairly stable.

~~~
huxley
Apple also has WebKit Nightly Builds where it might appear sooner:
<http://nightly.webkit.org/>

------
jontro
Very nice. I cant wait to use this feature.

Putting color codes in one variable will help a lot.

~~~
insertnickname
Only problem is that no one else supports it.

~~~
huggyface
You have to start somewhere. The only real question is whether it can be added
as a polyfill on browsers as they catch up.

~~~
bratsche
Nobody supports it yet _and_ it's already done better using preprocessors like
Sass. Your move, Sherlock.

~~~
huggyface
I like the part where people get so attached to a tool that they've learned
that they reject change. Like your message. Comparing a preprocessor to a
native element is asinine. Do you argue against JavaScript features because,
given that it's a turing complete language, such things could simply be done
with preprocessors?

Seriously the boorish comments about "no support yet" are like listening to
fat client advocates in the 90s.

~~~
bratsche
It's not so much about attachment to current tools. It's just that you look at
something like this, with all its cumbersome syntax, and wonder why they had
to make it so ridiculous. And it's not like nobody had any decent ideas of how
to do a nice, simple, clean syntax for variables. In the end I suppose we'll
be able to continue using preprocessors, and maybe they can generate the
clumsy native CSS variables, so it won't really matter and we'll get the best
of both worlds. But it sure would be nice if they wouldn't create new features
that instantly feel cumbersome to use compared to what people have already
been using.

