Native CSS Variables: Welcomed Addition or Huge Mistake?

Native CSS Variables: Welcomed Addition or Huge Mistake?

The web development community received some big news recently. While not yet in the nightlies, experimentations are, once again, underway, which will, if successful, provide us with native support for CSS variables, mixins, and modules in browsers. The question is, though, is this a good thing?


Pros

  • Maintain projects easier
  • Write less “code”
  • More streamlined integration with JavaScript
  • Update site-wide settings and params with a single value change

Cons

  • Should CSS be complicated?
  • Higher barrier of entry for designers
  • The current proposed syntax will seem too confusing for some

How Does it Work?

Before we progress, keep in mind that these developments are still only in the experimental stages. They have not been implemented in any browser just yet.

If you’re modestly familiar with CSS preprocessors, like Less or SASS, you’ll have a basic understand of what to expect from these additions. (That said, the proposed syntax unfortunately is a bit different.) In the future, you’ll have the ability to create variables (global and local), and mixins, which you can think of as a collection of stylings that can easily be referenced.

What Took So Long?

As long as I can remember, the community has been clamoring for CSS variables; so what was the hold-up? In a word: disagreement. In fact, back in 2008, webkit was toying around with this feature — even to the point of implementing it into the nightlies — though, the proposal stalled not long after. Many felt that morphing CSS into a more programmer-like language would only introduce frustration; some even felt that it might confuse designers. For example, if the primary color in your project is stored within a variable — presumably at the top of your stylesheet — it would then require the designer to refer to two locations.

@myColor : red;
/* Less syntax */
#someElem {
 color: @myColor;
}

While this argument is valid to some extent, it doesn’t hold much weight. Most designers maintain a set of site-colors at the top of their stylesheet, which they use for reference. Introducing variables to contain these values is a logical solution.


The Proposed Syntax

Less or SASS fans will be accustomed to defining variables like so:

 
/* Less */
@primary_color : red;

/* SASS */
$primary_color : red;

The proposed syntax complicates things a bit by making variables typed. For instance:

/* Declaration */
 @var primary_color color red;

/* Usage */
body {
  color: var(primary_color);
}

Worth Noting

  • All variables are prefaced with @var
  • Variables are typed. Note the use of the color keyword in the code above.
  • To access the value of this variable, we use the var function, and pass in the variable name.

I must admit: it does seems a bit redundant to use the @var directive. The syntax that SASS and Less uses seems more appropriate and cleaner. @myVar is more succinct than @var myVar.

Variables types are a welcomed addition, on the other hand.

Variables are typed. Every primitive value type, every property, and a few extra convenience types exist. This lets us expose the new CSSOM stuff on them: document.styleSheets[0].vars['primary_color'].alpha = .5;
xanthir.com

Local Variables

Variables will also have the ability to be scoped to a declaration box, via the use of the @local directive. This can be useful when a variable only needs to be used once or twice within a project.

.box {
  /* Declaration */
  @local box_gradient background linear-gradient(top, black, white);

  /* Usage */
  background: var(box_gradient);  
}

Mix-ins

Mix-ins can be incredibly helpful. In fact, we covered the process of creating a class file of mix-ins not long ago on Nettuts+. You can read about it here — though keep in mind that the technique(s) presented in that article rely on on the Less preprocessor. The new experiments, again, use a slightly different syntax.

/* Less */
.border-radius( @radius: 3px ) {
  -webkit-border-radius: @radius;
  -moz-border-radius: @radius;
  border-radius: @radius;
}

/* SASS */
@mixin border-radius($radius: 3px) {
  -webkit-border-radius: $radius;
  -moz-border-radius: $radius;
  border-radius: $radius;
}

/* And possibly the native solution?? */
@mixin border-radius(radius length 3px) {
  -webkit-border-radius: var(radius);
  -moz-border-radius: var(radius);
  border-radius: var(radius);
}

Note the similarities between SASS and the proposed native solution for mixins. This is due to the fact that members of the SASS team are serving as advisors.

Nesting

As you may be aware, Less and SASS allow you to nest selectors. This can drastically reduce the size of your stylesheets, as it’s removes the need to the same selector repeatedly.

/* The current way */
#content { ... }
#content p { ... }
#content p a { ... }
#content p a:hover { ... }

/* Less and SASS */
#content {
  ...
   p {
      ...
      a {
         ...
        &:hover { ... }
      }
   }
}

/* And natively?? */
#content {
   ...
   @this > p {
      ...
      @this > a {
         ...
         @this:hover {
            ...
         }
      }
   }
}

While the proposed syntax is more wordy, to its credit, it does have a nice OO-like syntax, which will make plenty of developers feel right at home.

But remember – not all designers are developers.

Namespacing

By default in Less, all variables are — for all intents and purposes — global. As a result, it becomes difficult to distribute code, as existing variable names can be over-written. The potential native solution will be to implement modules, or namespaces. They can then be included in a block by adding the @use directive.

 @module Site {
   @var primary_color color #292929;
   @var secondary_color color blue;

   @mixin border-radius(radius length 3px) {
      ...
      border-radius: 3px;
   }
}

/* Incorrect Usage */
body {
   color: var(primary_color); // Variable name is undefined
}

/* Correct */
body {
   @use Site;
   color: var(primary_color); // #292929 (Works)
}

Conclusion

As noted at the beginning of this article, the documentation listed above is still in the experimental stages. It’s possible — likely even — that the syntax will change, based upon your feedback. So let’s have it. Does the idea of native variables in mixins in your CSS excite you…or scare you?

Me? Well I’m for it. I think the proposed syntax could use a bit of work, as it will no doubt scare away the designers among us. That said, if the syntax was simplified a bit, I’m 100% on board. How about you?

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.fallingsquirreldesign.com Jordan Wiedbusch

    I love the idea of what is being thrown around with the new CSS. The big challenge though is adding all this functionality and keeping the whole thing down in complexity. CSS I think is best as something that is simple to understand and read by almost anyone.

    The number one thing that needs to be worked on is the syntax that is being put out on these. A lot of it such as the @var() and nesting could really be cut down into something a lot easier to read. I read the source post at the top and they were using $ as a variable marker, which I like a lot more then the var function adding more clutter to everything. The nesting also looks really messy as it is right now when you look it to some of the other options presented. Get a UX guy on the team to help with these things.

    With that, all of these new ideas would be a great improvement to what were using now. While it would not be something that could be relayed on as we have to make pages work with the lowest version of common web browsers, it would be very useful for a lot of progressive enhancement for the time being.

  • jem

    I think its a great idea.

    Important to note that though Tab Atkins Jr (the guy who made the post about this) works on Chrome and the CSS specification, this sounds like its just being developed experimentally under the hood of Chrome right now. I think its adoption in the actual CSS specification would be a much bigger matter where many other individuals’ opinions would come under consideration.

    I don’t think this will intimidate newcomers to CSS since you can technically continue on like these features don’t even exist (which they don’t.. and even if they appear in Chrome, they still really don’t exist in a way that any web developer will utilize them).

  • Reese

    “Should CSS be complicated?”

    Two things, to whomever considers this a con:

    1) CSS already IS complicated. This will merely alleviate some of the constant rewriting necessary to make ever-so-basic things happen. Just how you’re usually under no obligation to write object-oriented code in object-oriented languages (go ‘head witchyo bad functional self) , you are completely free to keep writing a billion background modifiers up and down the bloody page as long as your foolish heart desires.

    2) Motherfu**a, you’re working at a web design house, I’m assuming you’ve passed 7th grade Algebra. Stop holding the rest of the Interwebs back because the idea of a letter representing an expression throws you into a tizzy.

    • agush

      +1

  • http://www.admixweb.com Teylor Feliz

    Great idea, stupid implementation.

    • http://www.admixweb.com Teylor Feliz

      I also would like to know about performance rendering the page.

    • http://zecel.com Zecel Studios

      +1

  • Scott

    Meh. I’ve managed for years of CSS without any real need to use variables and nested blocks. Having said that, I can see how they are a useful addition (apart from @local and namespaces: completely unnecessary).

    The syntax leaves a lot to be desired though. Instead of @var for each variable, how about a block declaration like @vars { … }

  • Reda B.

    More confusing for web designers ? If that was true, LESS (and SAAS) projects wouldn’t be alive. If such preprocessors exist, it is because there is a need for them.
    Now variables mixins etc… in CSS, that is going to hurt backward compatibility. So no, thanks, not for now. And if we have to go in that direction, why not say goodbye to current css syntax and make javascript THE language for stylesheets. CSS in JSON, wouldn’t it be great ?

  • http://www.cdreamer.com Danz

    I think having native CSS variables would come in handy, esp when dealing with repeated hex values, such as colors and backgrounds.

    I like the nesting idea, purely for the aesthetics of the CSS.

  • http://www.suburban-glory.com/blog Andy Walpole

    Adding methods for reducing the size of a CSS file has got to be a good thing surely… and using tried and tested means as already used by programming languages seems like a good path to go down.

    I’m not sure about backwards capability with IE would work though… that could be a bit mad… although where there is a will there is a way…

    Also not sure whether the original article is describing constants or variables.

    Lets not forget that we had this discussion all before a few years back and it never came to anything.

    Another point is lets implement the CSS3 as laid down by the W3C first… there is SO MUCH more to implement.

    How about variables, mixins and the rest for CSS4?

  • http://www.onderhond.com/ Niels Matthijs

    The addition of css variables could make a lot of difference is used wisely. You know that a lot of people are going to mess it up and will make downright hell of their stylesheets, but that shouldn’t hold back the rest of us I think. Unless of course such a screwed up projects lands in your hands and you have to start cleaning it up. Which will happen at some point or another.

    As for the nesting, I’m not entirely sure what to make of the example above. For some reason the child selector is used, it’s not really clear whether that belongs to the @this syntax or actually represents a child selector. In the latter case, the examples don’t really match. Whatever may be, I believe readability is greatly reduced with such a syntax. Left-read selector reading is not enough, there’s a vertical dimension involved to construct the whole selector. And if people going to write 1 property/line css it will turn into one unreadable mess.

  • http://www.stephanmuller.nl Stephan

    I’d really like to be able to use nested styles and variables, but I really don’t like the notion of variable type declaration. I’m comfortable enough with some programming/scripting languages to be able to read and understand the basics, but in CSS it’d just seem like useless overhead to me.

    In fact, I think I’ll just try and give LESS a spin, see what it does for me :)

  • http://electroplankton.net Peter Duerden

    Anything that scares designers away from code is fine by me ;) After all, if designers did all the coding what would us developers do?

    I welcome this addition. And that’s the best part – it’s an addition. If it’s too code-like or complicated for some to use then carry on as before. No change needed. For those of us using Sass/Less it’ll be great to do things natively. The syntax is verbose by comparison but I’m sure there’s good reason behind the scenes.

  • JMWhittaker

    This makes so much sense and would be a welcomed extension to the current CSS specification. Having used SASS & Compass regularly over the last few months I would not code CSS without it. Mixins, variables and also cross browser includes make it a joy to use.

  • http://twitter.com/MatthewJuhl Matt

    Here’s a ‘con’ for your list: Less readable stylesheets.

    Who wants to have to scan through a bunch of stylesheets looking for a variable definition instead of just having the value right there with the declaration? Count me out.

    • agush

      1. CTRL + F

      2. Who wants to scoll upon thousands of lines of repeated declarations? I rather scroll to the top, find the variable color, than have p{…} p li{…} p li a{…} p li a:hover{…} , these techniques effectively reduce the number of lines, you currently need to do the same thing, plus it would be up to you to use this new syntax. So actually you will be the one doing the scrolling through long declarations, while others enjoy the benefits.

      • http://madebyrasmus.com Kalms

        +1

  • http://spronkey.com Keith Humm

    “Variables” in CSS is a terrible idea.

    Text replacement syntax is a brilliant idea.

    Looking at the designers here, they are all engraved in their palette. They have their set colours – usually from a pantone book, and load ‘em up in inDesign. It would be amazingly simple for the CSS implementors if we could simply define the colours by name in a CSS file (a la less/sass), and use them.

    However, I really do think that we should forego any programming concepts such as namespaces and, to be honest, variables, and simply have a text expander. For example.

    ~myborder {
    border: 1px solid #fff;
    border-bottom: none;
    box-shadow: …
    }

    h1 {
    ~myborder;
    }

    If we get anything more programmer-y than this, we’ll be wanting functions, too:
    ~textrhythm(baseSize) {
    line-height: // calculate from base size
    }

    Actually, now that I think about it, // syntax for comments would be damn nice…

  • http://jeffkoromi.com Jeff Koromi

    The reason I love CSS is because of how simple it is. Though variables could be powerful, making them too complicated wouldn’t be a good idea. There’s a fine line here between usefulness and making CSS unobtainable to non-programming types.

  • http://www.elimcmakin.com Eli McMakin

    Why stop with variables? Why not just go full OOP? That seems the direction that his is heading.

  • Chris Sanders

    I love the concept of CSS variables and nesting. However, the syntax is more verbose than it has to be to accomplish the same thing. Also if something is nested why does it need a > selector? In any case, where can I keep up with further developments on this front?

  • dismal

    blah, keep css as styling, keep your logic elsewhere.

  • http://www.ejsexton.com/ E.J. Sexton

    I do not see why these changes would “scare” anyone. The use of variables, mixins, nesting and namespaces are not required, and designers can continue writing CSS as they always have. Adding them should not make CSS inaccessible to designers, but I think like anything else, that will depend on how they are exposed to it. If they find a nice, designer-friendly “CSS for Beginners” tutorial, I think that most designers would be able to cope and even understand some of the functionality (such as how variables work)—especially if those designers have been exposed to JavaScript. If these same designers are using Web 2.0 sites or DreamWeaver to write their CSS for them, then they might not even be exposed to these features.

    Projects like Less and SASS would not exist unless there was a demand for this functionality. Others have mentioned this, and I think they have a valid point.

  • http://bibikova.com ben

    I think css is being overthinked. I can see condensing some elements and using a variable for say border radius. But for the most stuff, using practical smart css implimentation does the job as well.

    • http://madebyrasmus.com Kalms

      On small sites, yes. On big, global platforms; supporting a multitude of media sites – Not so much. And if you throw a responsive layout/grid into the mix, plus 2 external front-end developers – well, you do the math.

      Variables and mixins are incredibly useful, it makes it easy to adhere to the DRY principle and makes the code highly maintainable.

      Take it from someone who regularly juggles 4-6 different media sites, on any given day. I understand where you’re coming from, and nobody will force you to use the new extensions, but please don’t let that mindset belittle the real problems of CSS.

  • BJ

    *Yes please* to CSS variable, variable namespaces and nesting (scoping) – all 3 would be fantastically useful for reducing redundancy and repetition, making stylesheets easier to maintain. “Mixins”, typing and local vars I could take or leave, but I can see the benefit of typing to JS manipulation.

    A related extension that’s been around since ~IE5.5 is CSS Expressions and CSS Behaviors – again, it’s a discussion area as to whether this sort of stuff belongs within CSS. Expressions allow dynamic CSS values via a Javascript expression – e.g.:

    myElem { height: expression( window.innerHeight – 30 + “px” ); }

    CSS Behaviors allow Javascript behaviour and events to be attached to matching elements via CSS, instead of needing something like jQuery to set up the handlers etc. For example, can associate a behavior with all link elements (A) on the page, to customise what happens when clicking or mouseovering them.

    This makes it easier to create reusable presentation and functional enhancements to built in HTML elements, particular element classes, etc. The downside, as with any JS solution, is it’s possible to negatively affect performance if overused (as Dean Edwards ran into when constructing the “IE7.js” moderniser script and trying to attach complex behaviors to virtually every element on the page).

    Example:
    A { behavior: url( magicLinks.htc ); }

    magicLinks.htc then contains something like (can also contain properties, methods etc to turn each affected element into a full reusable, configurable component):

    function ShowMagicPreview() { … }

    Nothing you can’t do manually via a bunch of extra Javascript (though much easier now via something like jQuery), but the “reusable web component” idea was interesting and it’s a pity it didn’t catch on in other browsers (unlike some other IE inventions: XMLHttp, innerHTML, accessing elements via ID, etc).

    http://net.tutsplus.com/articles/general/what-internet-explorer-got-right/

    Cheers, BJ

  • BJ

    HTC example got chewed:

    function ShowMagicPreview() { … }

    Cheers, BJ

  • BJ

    One last try ;) Mod – please merge posts if poss!

    <public:component urn=”magicLinks”&gt
    <attach event=”onmouseover” handler=”ShowMagicPreview” /&gt
    <script&gt
    function ShowMagicPreview() { … }
    </script&gt
    </public:component&gt

    Cheers, BJ

  • Scott

    Why would you need local variables in css?
    Would you not simply hard code the parameter?

    CSS variables are a great idea, the implementation however looks like a group of ignorant non programmers are making the decisions.

    /* Declaration */
    @var primary_color color red;

    /* Usage */
    body {
    color: var(primary_color);
    }

    Considering the fact that every parameter in CSS is in fact a string,
    why then would you complicate matters by type casting the variables
    rather than just passing the string to the parameter?

    #000FFF is the string for a specific color.
    0px is a string for a pixel.
    If an integer or other non string parameter is necessary for a given
    object parameter such as the border width, the object should test
    and then if necessary, convert the string to it’s needed cast.

    Rather than having the developer call the var() function, the var()
    function should be called within the object’s rendering.

    Finally, if local and global variables are desired, just utilize different
    indicators as in the following examples:

    <table>
    <tr>
    <td>Local</td><td>Global</td>
    </tr>
    <tr>
    <td>$</td><td>@</td>
    </tr>
    <tr>
    <td>@</td><td>$</td>
    </tr>
    <tr>
    <td>$</td><td>$$</td>
    </tr>
    <tr>
    <td>@</td><td>@@</td>
    </tr>
    </table>

    For whatever reason, there are those who think that complexity
    and the ability to make things complex is equivalent to being
    highly intelligent. I am more of the opinion that such a compulsion
    is more indicative of an individual being insecure about his or her
    capabilities and attempting to compensate for their inadequacies
    by purposefully making those who do not grasp complicated
    technologies readily, feel stupid.

    Clearly, if one was of the superior intellect one desires to be seen
    as having, one would be aware of the fact that not everyone is gifted
    with such levels of ability and therefore, naturally strive to make things
    as easy to understand and utilize as ones superior intellect would
    advantage. Invariably following the philosophical principles of
    K.I.S.S. which is to say: Keep It Simple, Stupid!

    Scott A. Tovey

    • Scott

      Way to miss the purpose for pre as in preview:

      LocalGlobal

      $@

      @$

      $$$

      @@@

      Scott A. Tovey

      • Scott

        I shall correct myself one last time and be done with it.

        Local Global
        $ @
        @ $
        $ $$
        @ @@

        Scott A. Tovey

      • Scott

        Fine, I’ll just insert . to format my text.

        Local Global
        $……….@
        @……….$
        $……….$$
        @……..@@

        Scott A. Tovey