Advertisement

Native CSS Variables: Welcomed Addition or Huge Mistake?

by

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?

Advertisement