Software developer joke:
A developer, while at the grocery store, calls his wife and asks "Do we need anything from the store?" His wife replies "Yes, we need bread. And if they have eggs, get a dozen" The developer arrives home and to his wife's astonishment, he had bought a dozen loaves of bread.
In the Sass documentation, the @if
directive is said that it is a SassScript expression that will use the styles nested within the argument if the expression returns anything other then false
or null
.
But what does that mean? The ability to evaluate boolean logic is a basics feature of every programming language. This evaluation can involve a basic boolean variable or any other variable/expression that can be evaluated to true
or false
.
In the following example we will use the @if
control directive and a simple boolean variable to evaluate something like this:
$truthy: true !default;
$falsy: false !default;
@if $falsy {
@deubg "I am false";
} @else if $truthy {
@deubg "I am truth";
}
Running this code we get the following output:
@deubg "I am truth";
But why? What's interesting about this example, the value of $falsy
is false
, so this meets the criteria of being either false
or null
. As a result, the @if
statement then reviews the @else if
query to evaluate it's boolean value. As a result, $truthy
comes back as true
so Sass will print out the rules from within. @else if
works in Sass much like other languages, whereas @else
will simply return a rule when all other queries have failed and @else if
must be evaluated and come back as true
before the rules are used.
If we were to update the variables being set to the following, we would get a different response:
$truthy: null !default;
$falsy: true !default;
Resolves to:
@deubg "I am false";
And as long as we are talking about it, the @debug
directive simply prints the value of a SassScript expression to the error output stream. This is a pretty useful tool when debugging Sass files that contain complicated SassScript, for example:
$val: 100;
$var: 1984;
.block {
@debug $val != $var;
}
When processed, Sass will return:
<file name>.scss:<lione number> DEBUG: true
Using @if
also allows for the use of OR
or AND
operators to evaluate multiple logical values. For example, in the following code, we have two variables. One with an empty list and the other with a list containing two objects. The @if
statement will evaluate if the length of empty list is greater then '0
OR if the length of $test-listis greater then
0`.
$empty-list: () !default;
$test-list: (test me) !default;
@if length($empty-list) > 0 or length($test-list) > 0 {
@debug "I have a list";
} @else {
@debug "where is my list?";
}
Conversely, using the and
operator, we can evaluate if one thing AND another are true.
$empty-list: () !default;
$test-list: (test me) !default;
@if length($empty-list) > 0 and length($test-list) > 0 {
@debug "I have a list";
} @else {
@debug "where is my list?";
}
Much like the @if
directive, the if()
function evaluates if something is true or not and then provides the appropriate return. The syntax is pretty simple, as illustrated in the following:
if(condition, true, false);
But how do we make use of this? Let's say for example we have a need to evaluate the value of a variable and make sure that it is actually a color. Using the @if
directive, we could write something like the following. Pretty simple really. When using the function of color()
pass in a color value or something totally off base. The function will use the built in Sass function to evaluate what type the passed in value is. If it is a color, then return the color. If it is not, return a null
value.
@function color($val) {
@if type-of($val) == color {
@return $val;
} @else {
@return null;
}
}
To use this, simply reference the function with a CSS attribute in this example. Here the function will return a null
value and thus the CSS rule would not be printed out. NOTE, there is a bug in libsass where the null
value will be printed out.
.block {
color: color(foo);
}
Using the new if()
function, we can actually wrap all this logic up into a single line of code. Remember the syntax?
if(condition, true, false);
Knowing this, to re-factor the previous code, just do the following:
@function color($val) {
@return if(type-of($val) == color, $val, null);
}