Hacker News new | ask | show | jobs
CSS Variables in Firefox 31 – new syntax (jan.rs)
77 points by reimersjan 4349 days ago
12 comments

That new syntax is astonishingly ugly and bizarre.

I'm sure it'll be a real joy to use that for anyone who's been using Sass or Less (and who doesn't, these days...).

Yeah, obviously they need to avoid conflicts but surely they could have found a single character to use as a prefix instead of "--", like "$" or "@".

The "var()" function is just.. redundant. Or maybe I'm missing something?

Here's the discussion where they changed from "var-" to "--":

http://lists.w3.org/Archives/Public/www-style/2014Mar/0261.h...

And later on the justification for not using $ or @:

http://lists.w3.org/Archives/Public/www-style/2014Mar/0400.h...

There's also the issue that this needs to be backwards compatible with parsers that don't support the syntax, and apparently because the variables cascade that makes it harder still. I agree it's ugly though.

From the second link in parent:

"> As far as I understand, the main reason of why Tab's original idea of using `$` has eventually been dropped was some uncertainty about its possible extensibility for being used in property _names_ besides property _values_.

The reason it got dropped is that some people (including Tab) do believe we should reserve $ for mixins and other preprocessor-like operations which may potentially be added to the language at some point. e.g. futuristic things like:

    @define apply-2d-transform(initial-scale, initial-rotation, ...) {
        ...
        my-transform-scaling: $initial-scale;
        my-transform-rotation: $initial-rotation;
        ...
        transform:
            scale(get(my-transform-scaling))
            rotate(get(my-transform-rotation))
            translate(get(my-transform-translation));
        will-change[]:
            transform;
    }

    .some-element {
        $apply-2d-transform(...);
        transition[]: transform 0.5s ease-in-out;
    }

    .some-element:hover {
        my-transform-scale: 1.1;
    }
but this syntax was just made for this example, final milage may look completely different and/or offer different features)"
I don't get that argument. Sass manages to avoid $ conflicts while using it for both variables and mixins. Its nice clean, consistent syntax. I don't see why we need different syntax for the two. Eg:

  $myColor: #fff;

  a {
    color: $myColor;
  }

  @mixin border-radius($radius) {
    -webkit-border-radius: $radius;
    -moz-border-radius: $radius;
    -ms-border-radius: $radius;
    border-radius: $radius;
  }

  .box { @include border-radius(10px); }
This is just stupid. Here are some sigils they could have easily used without much issue: #, *, +. They could have also used something like [var-name] or <var-name>.

I am convinced that at this point CSS is a clusterfuck that should be killed with fire.

And one thing we should kill it with is GSS. (http://gridstylesheets.org)

Watch the video!

Variable is a BIG change in CSS. If a browser doesn't support variable, then new stylesheets are already broken in that browser. It makes little difference to make the syntax compatible.

Once an easy-to-use syntax is published, toolchains that parse CSS will update as fast as they can! But "--"? Everybody will stick to the old standard and never want to upgrade.

where is the discussion for using `var()` ?

The rationale for the "--" sigil matches what I'd expected, but I don't understand: why not just `name: --value` ?

`--` is a comment in many languages (sql, haskell, ..).
And of course it's a decrement operator in many others! It doesn't seem at all intuitive as a sigil to use for this purpose.
Does the W3C not have internet access to learn about existing solutions and least try to emulate the good parts?

LESS and SASS are much better about variables, what the heck were they thinking?

    background-color: var(--best-gray-ever);
Not exactly intuitive or easy to parse at a glance.
> what the heck were they thinking?

I don't know, maybe about how to design a spec that is compatible with past and future CSS parsers and features?

People think it's so simple to come up with a new feature for CSS/HTML/JS, when actually, they have no idea how difficult it is.

They're smarter than that: http://www.xanthir.com/blog/b4KT0

Sure,but when the spec is bad at first place,no new feature can be good.So hell yeah ...

> what the heck were they thinking?

...At first place when they wrote CSS.

CSS is a disaster,and one of the worst spec ever written in my book.

> People think it's so simple to come up with a new feature for CSS/HTML/JS, when actually, they have no idea how difficult it is.

Aside from HTML,CSS and JS are "defacto" standards since vendors werent able to agree on a better spec when they should have. only developpers can fix these with tools they build.Devs cant rely on these technologies on their own.That's why they have CSS and JS preprocessors.Because while it's crap at the end of the day devs need to build on top of that crap.

The w3c has been failing at their job for some 15 years now. Enabling drm in html5 and giving the mpaa a seat on their board should have been the last straw. Ignore them, and start looking to WhatWg
Most of the members of whatwg also like the DRM bits.
These are not like SASS variables. I think calling this variables is causing unnecessary confusion.

This feature adds custom properties. CSS had custom vendor properties like `-webkit-foo`, and now you can have your own properties with vendor == "", so it's `--foo`.

I think this is just a problem of nomenclature. In CSS, a statement such as

  font-color : red;
comprises a "property" (left) and a "value" (right). The draft W3C proposal allows you to specify a "custom property" and assign a value to it, thus:

  --header-bg-colour : #ff5533;
You can then reference this elsewhere by saying:

  header { background-color : var(--header-bg-colour); }
Isn't that just how you use a variable (written as $header-bg-colour) in Sass?
The similarity is only superficial. SASS variables are lexically scoped. CSS properties are cascading.
There is that. Over in the real world, I suspect most people will put their CSS variables in ::root and leave it at that.
So in this article, the author says this is not supported on chrome. But in this stack question [1], chrome is clearly using it. Is the only difference the author is discussing that now firefox uses/supports "--" instead of "var-"?

[1] http://stackoverflow.com/questions/18466569/enable-experimen...

CSS variables were recently removed from Chrome: http://stackoverflow.com/a/23518831/349353
I see, thanks for pointing that out.
I like it. The syntax actually feels more css-like to me than what most preprocessors use. But never mind the syntax, the killer feature us the cascading - that's what sells me on this vs SASS/LESS/etc. (And, having it native is also nice - this way I can just dump something on Github Pages and skip the compilation step.)
Can you suggest a use-case where the cascading variables is a helpful thing?
Can anyone think of a use case for this beyond what a precompiler (Sass, Less, Stylus) can do?
For one, it means that you don't need to have a precompiler step in the development process. You can more easily edit the value inline in your browser's developer tools. You can more easily put together simple static sites.

Another is that you can use it in conjunction with calc(), which you can't do in a preprocessor. Take a look at some example use cases for calc, which can't be done in a preprocessor: http://css-tricks.com/a-couple-of-use-cases-for-calc/ Now instead of just using constant values in those, you can use variables. This can be even more powerful for responsive designs, because you can set the variable to different values based on a media query.

I couldn't think of a very good example, but here's something: http://codepen.io/anon/pen/vuyAI

The CSS use a couple of custom properties that define the foreground and background colors. Then, some elements redefine those custom properties (through CSS or JS) and that in turn makes all their children inherit the new custom properties' values and change their styles. This makes the rules that use the custom properties very general, and avoids the need to write more specific rules for the alternative colors. I hope this makes sense :)

I don't think this is possible to do with CSS preprocessors.

I think the idea is you use this rather than a precompiler.
Changing bootstrap theme colors on the fly would be one reason to use this, even though you might be compiling bootstrap on each build.
Because precompilers are sort of a disruption of the point of CSS to begin with. I know, I know, a lot of people use them, but using style sheets that require compilation pretty much defeats the purpose of separation.
Yes and no. The browser has to parse the CSS, and it's most likely building an abstract symbol tree. So in a sense CSS is compiled too, it just happens in the browser so web developers don't have to be aware of it.

Do you remember the type attribute?

    <style type="text/css">...</style>
That was originally put there so we could have different types of stylesheet languages, instead of everyone having to use CSS all of the time. Maybe browsers should incorporate the most popular LESS and SASS projects so that they can support type="text/less" and type="text/sass" too. Some workaround will be needed for old browsers (a javascript shim that retrieves server-compiled css) during the transition period, but eventually we'd end up with being able to use LESS, SASS, and CSS where needed, interchangably.
Woah. CSS variables look like compiler flags. There goes the W3C reinventing the wheel when Sass, Less and others have already laid out how to assign variables just fine for years.
As other posts have stated, CSS variables are not the same thing as preprocessor variables. Specifically, they cascade.

A preprocessor cannot possibly implement CSS variables with cascading because it the value is resolved against a live context.

In other words, you can actually change the variable at runtime with rules that target different selectors.

As such, the "variables" are in fact functions.

Thanks for the break down. I'm not seeing the benefit of variables cascading, though.
I agree, I need to see a use-case for having cascading variables. The fact that they do seems to go against some of the benefits of them in the first place.
Why do you have to use var(--name) when the parser already knows it's a variable from the -- prefix? Surely property: --name; is nicer than property: var(--name); ?
Does anyone know if the var() function only work with the variables? For example, can I do something like:

  background-color: var(color);?
In case you didn't know, there's already a special version of the `inherit` keyword for using the color value in other properties:

    background-color: currentColor;
Fully supported in all modern browsers. http://devdocs.io/css/color_value#currentColor_keyword
Writing your styles in javascript is a better option. You get variables, as well as functions and modules (e.g. with browserify), all with sane syntax and semantics (no "cascade").

Preprocessors are an inferior solution, limited by the semantics of CSS and leading, by the pervasive use of macros, to needlessly large CSS file sizes.

What's the best solution for writing styles exclusively in JS and avoiding CSS completely?
My practice is to build the DOM programmatically with jQuery, and add styles to the elements directly

   $("<div>")
     .css({width: 100, height: 20, color: 'red'})
     .appendTo(container);
Then, since these are just values in normal javascript code, you can refactor as normal. Pull commonly used patterns out into functions (e.g. `importantText(16, "size 16 important text goes here")`).

Most styles in the applications I write tend to be inextricably linked to the layout and function of a component (e.g., tabs should be next to each other); in the rare case that a style needs to be customized in different locations or at different times, it becomes a parameter (e.g. `confirmDialog(textStyle, message, onOk, onCancel)`)

No extra tools are needed, beyond jQuery (building up the DOM without jQuery or something like it is awful).

I've made this argument before, using JS exclusively for styling does not let you avoid CSS. It lets you avoid certain aspects of CSS that may, or may not, be helpful.
And does your styling work in a webbrowser where JS is disabled?
Not trolling, I really don't understand: why would you disable JS when browsing the web?
Not wanting to execute arbitrary untrusted code on your machine? While there has been lots of good work put into sandboxing browser by the browser vendors, the ability for attackers to run custom code within the browser makes many exploitable vulnerabilities a lot easier to exploit. Things like the various privacy leaks based on cache timing, visited link styles, and so on, or just exploiting buffer overruns that have been protected against by address space layout randomization but with arbitrary code the exploit can try the same thing over and over again with different size inputs until it finds one that works.

Running JavaScript in your browser automatically from any site that you visit is pretty darn scary when you think about it. You can protect from a whole host of vulnerabilities by disabling it, and then whitelisting only hosts which you trust.

Viewing some overly crufty sites can benefit from having JS completely off rather than "simply" using an ad-blocker. I'd wager that some tinfoilhats still run with JS off, or at least NoScript almost everything.
I'd rather use reactjs to style everything than this.
That doesn't make sense.
Ugly as hell. Go back to the drawing board.