One of the most common elements in programming languages is the if/else
conditional construct. It allows you to execute a code fragment based on the condition.
Before we go any further, let's deal with the concepts introduced above:
- A terminal construct guides the script along one of several paths, depending on whether the condition within the construct is true or false
- Condition is any expression we can reduce to either true or false. For example, the expression
2 + 2 = 4
is true, but2 + 5 = 1
is not
Let's take a simple example with mixins. Suppose the designer sent us a layout with two different color schemes: light and dark. Depending on what we specified in the project settings, we need to use either one or the other color scheme.
Let's describe both color schemes the designer sent us in the card
mixin. Let's try to make two schemes with the knowledge we have now:
@mixin card {
// Colors for the light theme
$primary-color: #f9f9f9;
$text-color: #424242;
// Colors for the dark theme
$primary-color-dark: #161625;
$text-color-dark: #e1e1ff;
.card {
.card-body {
&.light {
background: $primary-color;
color: $text-color;
}
&.dark {
background-color: $primary-color-dark;
color: $text-color-dark;
}
}
}
}
The result is a rather CRUD construction. We put the choice of color scheme on the classes light
and dark
. It turns out that for all elements we will have to use such constructions and add classes. This will lead to terrible confusion and constant problems due to forgetting to put a class for an element. The approach is workable but would create additional problems. It's also possible to introduce more global classes light-theme
or dark-theme
for body
. But that way, we get large sections of code with different designs that are also hard to keep track of.
How can SASS help here? We can use conditional constructs and declare the initial setting of the project's theme as a separate variable in advance. Later on, that setting will affect the entire project. It is more convenient to control the theme selection by changing just one variable.
So how to do it? Let's introduce a $dark-mode
variable with a true
value. As we remember, the boolean data type can take one of two values. In this case, true
means true. So we want to use a dark theme:
$dark-mode: true;
Now we can use the @if
construct in which we put a condition on the truth of the variable $dark-mode
in parentheses. This can be done using the ==
operator. We will discuss all such operators below. Let's return our mixin and add a condition:
$dark-mode: true;
@mixin card {
// Colors for the light theme
$primary-color: #f9f9f9;
$text-color: #424242;
@if ($dark-mode == true) {
// If the condition works, we overwrite the values of the variables
$primary-color: #161625;
$text-color: #e1e1ff;
}
.card {
.card-body {
background: $primary-color;
color: $text-color;
}
}
}
What happened here? At the mixin's beginning, we defined the default base colors. These were the settings for the light theme. Below we see a conditional construct @if
in which we check if the value of the $dark-mode
variable is true
.
Since we set this value at the beginning of our code, we rewrite the variables $primary-color
and $text-color
inside the card
mixin with those specified in the body of the condition.
The @if
operator produces one of two values:
true
— the expression inside the operator is true, and then we enter the body of the@if
constructfalse
— the expression inside the operator is false, and then we ignore everything inside the@if
construct
The result of compiling the SASS file:
.card .card-body {
background: #161625;
color: #e1e1ff;
}
Comparison operators
In the last example, we saw ==
— one of the comparison operators. It indicates the equality of the left and right parts of the expression. If they are equal, it returns true
. The compiler enters the body of the construct inside @if
.
In addition to this, several other comparison operators to know:
!=
is not equal. The result is exactly the opposite of the==
operator. If the left and right parts of the expression are not equal, the result istrue
>
— the left side of the expression is more than the right side>=
— the left side of the expression is greater than or equal to the right side<
— the left side of the expression is smaller than the right<=
— the left side of the expression is less than or equal to the right side
Where would we need such expressions? Suppose we have some font-size
value. If this value is less than 16 pixels, then with a viewport width of 768px, it should be increased by half:
$main-font-size: 14px;
html {
font-size: $main-font-size;
}
body {
padding: 1rem 3rem;
}
@media (max-width: 768px) {
@if ($main-font-size < 16px) {
html {
font-size: $main-font-size * 1.5;
}
}
}
If you compile this SASS file, you will get the following CSS code:
html {
font-size: 14px;
}
body {
padding: 1rem 3rem;
}
@media (max-width: 768px) {
html {
font-size: 21px;
}
}
Now suppose that we overwrote the value of $main-font-size
and set its value to 16px somewhere in the project:
$main-font-size: 14px;
html {
font-size: $main-font-size;
}
body {
padding: 1rem 3rem;
}
// 1000 lines of code later
$main-font-size: 16px;
// And a dozen more lines later
@media (max-width: 768px) {
@if ($main-font-size < 16px) {
html {
font-size: $main-font-size * 1.5;
}
}
}
Let's compile this code and get the following CSS code:
html {
font-size: 14px;
}
body {
padding: 1rem 3rem;
}
Now the $main-font-size < 16px
condition returned false
. The compiler did not go into the body of the conditional construct, so we do not process the code inside the conditional construct.
Logical operators
In addition to comparison operators in SASS, there are also logical operators. There are much fewer of them, don't be scared :) Boolean operators allow you to combine several conditions into one expression.
Let's go back to the color scheme example. Suppose we make specific styles for mobile devices where we should use the dark theme. Let's introduce an additional variable in which we specify the device type. It will help us set properties only for a group of devices and compile styles for them:
$dark-mode: true;
$device: 'mobile';
@mixin card {
// Colors for the light theme
$primary-color: #f9f9f9;
$text-color: #424242;
@if ($dark-mode == true) {
// If the condition works, we overwrite the values of the variables
$primary-color: #161625;
$text-color: #e1e1ff;
}
.card {
.card-body {
background: $primary-color;
color: $text-color;
}
}
}
How do we verify that both conditions for choosing the dark theme are true? We can create a conditional construct within a conditional construct (hello to the movie Inception):
$dark-mode: true;
$device: 'mobile';
@mixin card {
// Colors for the light theme
$primary-color: #f9f9f9;
$text-color: #424242;
@if ($dark-mode == true) {
@if ($device == 'mobile') {
// If the conditions work, we overwrite the values of the variables
$primary-color: #161625;
$text-color: #e1e1ff;
}
}
.card {
.card-body {
background: $primary-color;
color: $text-color;
}
}
}
Note: Don't get carried away with nested conditional constructions. Such staircases are hard to read. In addition, it is easy to make a mistake when adding or removing a condition.
We can eliminate this staircase with the logical operator and
. It will combine conditions and return true
provided both expressions return true
.
We have to add the keyword and
between the two expressions as follows:
$dark-mode: true;
$device: 'mobile';
@mixin card {
// Colors for the light theme
$primary-color: #f9f9f9;
$text-color: #424242;
@if ($dark-mode == true and $device == 'mobile') {
// If the conditions work, we overwrite the values of the variables
$primary-color: #161625;
$text-color: #e1e1ff;
}
.card {
.card-body {
background: $primary-color;
color: $text-color;
}
}
}
There are a total of three logical operators in SASS:
and
— the AND logical operator, it returnstrue
if both expressions are trueor
— the OR logical operator, it returnstrue
if at least one expression is truenot
— is a logical negation operator NOT, it returnstrue
if expression is false
Operator else
With @if
, we got the hang of it. Now, we have one question: what is @else
? It's simpler than it may seem at first sight. The code block inside @else
will be executed if the expression in @if
is false. All we need to do is add a construct @else
after the @if
block. In the color scheme example, we can rewrite the code as follows:
$dark-mode: true;
$device: 'mobile';
@mixin card {
$primary-color: white;
$text-color: black;
// We create variables before if/else conditions and only change them in conditions
@if ($dark-mode == true and $device == 'mobile') {
// If the conditions work, we overwrite the values of the variables
$primary-color: #161625;
$text-color: #e1e1ff;
} @else {
// Colors for the light theme
$primary-color: #f9f9f9;
$text-color: #424242;
}
.card {
.card-body {
background: $primary-color;
color: $text-color;
}
}
}
That's the tricky part. In this way, we can select the block of code that will be executed depending on the condition inside the @if
operator. Note, however, that you can often do without the @else
operator. In all but the last example, we overwrote the value of a variable if we chose a dark theme. It is the right approach because we set some colors by default and trivialize less code.
Are there any more questions? Ask them in the Discussion section.
The Hexlet support team or other students will answer you.
For full access to the course you need a professional subscription.
A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.