Sass in the Real World: book 1 of 4

Core data types

Sass, like many languages, consist of a series of core types. A data type, or simply type, is a classification for identifying one of various types of data from which a language can operate with. Data types typically consist of real, integer or Boolean values that determine the possible outputs for that type. Sass' data types are:

  • numbers (e.g. 1.2, 13, 10px)
  • strings of text, with and without quotes (e.g. "foo", 'bar', baz)
  • colors (e.g. blue, #04a3f9, rgba(255, 0, 0, 0.5))
  • booleans (e.g. true, false)
  • nulls (e.g. null)
  • lists of values, separated by spaces or commas (e.g. 1.5em 1em 0 2em, Helvetica, Arial, sans-serif)
  • maps from one value to another (e.g. (key1: value1, key2: value2))

Numbers

Sass numbers consist of floating point values, integers, and values with units. In the following example the parentheses are being used as a separator to maintain the order of operations so that the floating point value is divided by integer and then multiplied by the value with the unit.

By the way, multiplying a floating point or integer by a value of 1 with a unit is a very common pattern for adding a unit to a unit-less number.

SCSS

block {
  width: (9.9 / 3) * 1em;
}

CSS

block {
  width: 3.3em;
}

Strings

CSS specifies two kinds of strings: those with quotes, such as double quotes "Lucida Grande" or single quotes 'http://sass-lang.com', and those without quotes, such as sans-serif or bold. SassScript recognizes all kinds. In general if one kind of string is used in the Sass document, that kind of string will be used in the resulting CSS.

String operations

String operations allow you to build phrases on the fly by concatenating a series of variables that consist of strings.

SCSS

$foo: 'foo';
$bar: bar;

block {
  content: $foo + $bar;
}

CSS

block {
  content: "foobar";
}

Interpolation

Consider interpolation as a 'replacement' method. In some cases the value of a variable cannot be used when creating different types of strings in the processed CSS. A very common use case is when you are using the value of a variable to create a CSS attribute as illustrated in the following.

SCSS

@mixin firefox-message($selector, $value) {
  body.firefox #{$selector}:before {
    content: "Hi, Firefox users!";
    content: "I ate #{5 + $value} pies!";
  }
}

@include firefox-message(".header", 10);

CSS

body.firefox .header:before {
  content: "Hi, Firefox users!";
  content: "I ate 15 pies!";
}

Colors

If it can be written in CSS, it will work in Sass. In addition, Sass supports a wide range of Color Operators. All arithmetic operations are supported for color values, where they work piecewise. Meaning operation are performed on the red, green, and blue components in turn. For example:

SCSS

div {
  color: #010203 + #040506;
  background: #010203 * 2;
  border: rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75);
  background-color: blue + red;
}

CSS

div {
  color: #050709;
  background: #020406;
  border: rgba(255, 255, 0, 0.75);
  background-color: magenta;
}

Sass also has support for a large range of names colors that are indistinguishable from typical strings. See the full list of colors as written in the code-base itself.

Boolean

SassScript supports and, or, and not operators for boolean values. When using either and or or evaluators you are required to wrap the evaluation in parentheses () as illustrated in the examples below.

SCSS

$alpha: red;
$beta: green;
$charlie: yellow;
$delta: red;

.block {
  @if $alpha != $beta {
    content: 'winner!';
  } @else {
    content: 'loser!';
  }
}

.block {
  @if $alpha == ($beta or $charlie) {
    content: 'winner!';
  } @else {
    content: 'loser!';
  }
}

.block {
  @if $alpha == ($beta and $delta) {
    content: 'winner!';
  } @else {
    content: 'loser!';
  }
}

Null

Null values are treated as empty strings for string interpolation. The best use case for null is when you need to define a value, but don't have a specific value to be used. When Sass encounters an empty string, it's default functionality is to NOT print out the CSS. In this example, if we have an empty selector, Sass will not output any CSS.

.selector {

}

But you can't set an empty string to a variable. In this example, a common practice of using empty quotes, Sass will output that as a value.

$color: ' ';

.block {
  color: $color;
}

The output CSS will be:

.block {
  color: " ";
}

But if we use a null value:

$color: null;

.block {
  border: 1px solid $color;
  color: $color;
}

We would expect the following:

.block {
  border: 1px solid;
}

Lists

Lists are how Sass represents the values of CSS declarations like margin: 10px 15px 0 0 or font-face: Helvetica, Arial, sans-serif. Lists are just a series of other values, separated by either spaces, commas ,, quotes " " or parentheses (). In fact, individual values count as lists, too: they're just lists with one item.

There are some rules you need to be aware of when building a list. Due to all the operator types, you can actually build out a list in the following way, this will actually create 10 individual strings in the list.

SCSS

$string: this is a string of words "more words" then even 'more words';

While it is common to see lists separated with commas, e.g. $var: red, blue, yellow, since spaces are an operator, this is pretty redundant. The following examples produce the exact same number of items in the list.

$string: this is a string of words more words then even more words;

$string: this, is, a, string, of, words, more, words, then, even, more, words;

Parentheses () on the other had, you can use as separators, but these are most commonly used when you want to group different styles of values within a given list item. Keep in mind that strings within parentheses need to be in quotes. The following example will represent 3 items within the list.

$string: (12 "foo" 8em) (9 "bar" 1px) (66 "baz" 100%);

Again, you will commonly see examples where there are commas between the parentheses as illustrated below.

$string: (12 "foo" 8em), (9 "bar" 1px), (66 "baz" 100%);

While this works, it is unnecessary in this example because of the spaces. And to even point out, since we are using parentheses to group the items in the list, we don't even need the spaces, but it does help for readability.

Alone, lists don't provide any output for CSS. In most cases you will see lists used in conjunction with loops or cherry picking values using the nth() function. The nth() function provides a method to seperate a list into its assembled values. The following is an example of nth() functiona usage:

SCSS

// Browser prefixes
// -------------------------
$browser: -moz- -webkit- -o- -ms-;

.border-image {
  #{nth($browser, 2)}border-image: url("/files/4127/border.png") 30 30 repeat;
  #{nth($browser, 3)}border-image: url("/files/4127/border.png") 30 30 repeat;
  border-image: url("/files/4127/border.png") 30 30 repeat;
}

CSS

.border-image {
  -webkit-border-image: url("/files/4127/border.png") 30 30 repeat;
  -o-border-image: url("/files/4127/border.png") 30 30 repeat;
  border-image: url("/files/4127/border.png") 30 30 repeat;
}

Maps

Maps represent an association between keys and values, where keys are used to look up values. They make it easy to collect values into named groups and access those groups dynamically.

Note the syntax, in SCSS there is a semi-colon that follows the declaration as this is a single Sass statement. List-maps have no direct parallel in CSS, although they're syntactically similar to media query expressions.

$name-space: (key: value, key: value);

Making use of List-Maps typically is done with the map-get function. When using List-Maps, the variable is commonly referred to as the name-space. In this example I will create the $input name-space and nest some key:value pairs within it.

$input-disabled-color: #333 !default;

$input: (
  disabled-background lighten($input-disabled-color, 75%),
  disabled-border lighten($input-disabled-color, 50%),
  disabled-text lighten($input-disabled-color, 50%)
);

To extract these values we will use map-get function and pass in the name-space and the key from which we intend to get it's value.

input[disabled] {
  background-color: map-get($input, disabled-background);
  border-color: map-get($input, disabled-border);
  color: map-get($input, disabled-text);
}

In our output CSS I would expect something like the following:

input[disabled] {
  background-color: #f2f2f2;
  border-color: #b3b3b3;
  color: #b3b3b3;
}

As you can see, using list-maps can drastically change how you manage and maintain a series of related variables and their values.