CSS PREprocessors

Variables

by

CSS is extremely repetitive. And if you are working on a big, complex project you will have identical values/colors all around the place. When the time comes for a minor modification or a global refactoring chances are that you will forget to change something somewhere.

This article is covers only basic uses of variables, for more advanced use check the Variable Interpolation article.

Here is the basic syntax for variables.

@text-size: 10px;
@font: Arial, Helvetica, sans-serif;
@prim-color: #1bc2ff;

body {
  color: @prim-color;
  font: 400 @text-size @font;
}
$text-size: 10px;
$font: Arial, Helvetica, sans-serif;
$prim-color: #1bc2ff;

body {
  color: $prim-color;
  font: 400 $text-size $font;
}
$text-size: 10px
$font: Arial, Helvetica, sans-serif
$prim-color: #1bc2ff

body
  color: $prim-color
  font: 400 $text-size $font
$text-size = 10px
$font = Arial, Helvetica, sans-serif
$prim-color = #1bc2ff

body
  color: $prim-color
  font: 400 $text-size $font
$text-size: 10px;
$font: Arial, Helvetica, sans-serif;
$prim-color: #1bc2ff;

body {
  color: $prim-color;
  font: 400 $text-size $font;
}
body {
  color: #1bc2ff;
  font: 400 10px Arial, Helvetica, sans-serif;
}

Lazy loaded variables

Only Less supports lazy-loaded variables - you can type the variable even after the place you are calling it from and it will work. For example, this Less code works:

.vars-at-bottom-work {
  foo: @var;
}

@var: bar;
.vars-at-bottom-work {
  foo: bar;
}

Default values

Default values for variables work just like regular values, but if both are declared, the latter will take precedence.

Such default values can be useful for cases when you are not sure whether a regular value for a variable is or will be declared.

$var1: lorem !default;

$var2: bar;
$var2: default-text !default;

.default-variables {
  foo: $var1 $var2;
}
$var1: lorem !default

$var2: bar
$var2: default-text !default

.default-variables
  foo: $var1 $var2
$var1 ?= lorem

$var2 = bar
$var2 ?= default-text


.default-variables
  foo: $var1 $var2
.default-variables {
  foo: lorem bar;
}

Less does not support setting a default variable, this has been discussed before a number of times and Less is unlikely to get this feature, as its variables are lazy-loaded (see the previous section) and this may lead to confusion.

Scoped variables

All preprocessors support scoped variables - they work only within the context they are defined in, and can be useful to avoid interference with similarly named variables.

Scoped variables work only within the current selector and all child selectors.

Note that Stylus allows another way of doing this - by defining the variable and the value at the same time.

@var: 100;
.has-local-var {
  @var: 200;
  foo: @var;
  bar: @var;
}
.takes-global-var {
  foo: @var;
}
$var: 100;
.has-local-var {
  $var: 200;
  foo: $var;
  bar: $var;
}
.takes-global-var {
  foo: $var;
}
$var: 100
.has-local-var
  $var: 200
  foo: $var
  bar: $var
.takes-global-var
  foo: $var
$var = 100
.has-local-var
  $var = 200
  foo: $var
  bar: $var
.takes-global-var
  foo: $var
$var = 100
.has-local-var
  foo: $var = 200
  bar: $var
.takes-global-var
  foo: $var
$var: 100;
.has-local-var {
  $var: 200;
  foo: $var;
  bar: $var;
}
.takes-global-var {
  foo: $var;
}
.has-local-var {
  foo: 200;
  bar: 200;
}
.takes-global-var {
  baz: 100;
}

Property lookup

Stylus supports another feature that is not yet present in other preprocessors - property lookup.

It works close to how scoped variables operate. In the example below you will see that the .child bubbles up until it finds a @foo.

.property-lookup
  height: 200
  margin-top: (@height/2)
.property-lookup {
  height: 200;
  margin-top: resolve(@height / 2);
}
.property-lookup {
  height: 200;
  margin-top: 100;
}

Property lookups, just like scoped variables are a great way to center an object. For example, you can set a negative margin-left that is half the width of the object, and a margin-top that is half its height, in addition to left: 50% and right: 50%.

Variables accept many formats

All preprocessors allow you to set the following data types as variables

In addition to the above, Sass and Stylus support mapping values from maps/hashes, something that Less is currently lacking.

Interactive

Leave a comment below or suggest improvements on GitHub.