Variables are one of the most powerful tools in SASS. They make life a lot easier when you're maintaining a project.
Variables mean you don't have to repeat lots of code. Let's see how it works by creating a color scheme for a project as an example. Let's take a few colors that we want to use:
- Dark —
#303846
- Light —
#f7f7f7
- Basic —
#09d3ac
- Secondary —
#2196f3
Now we can declare variables at the beginning of our SASS file and write these values to them. We do it using the $
symbol and specifying a unique name:
$dark: #303846;
$light: #f7f7f7;
$primary: #09d3ac;
$secondary: #2196f3;
Now we can use these colors in any part of our project simply by referring to them by name:
.card {
background: $light;
border: 1px solid $dark;
}
The result of the compilation is the following CSS code:
.card {
background: #f7f7f7;
border: 1px solid #303846;
}
Like the template selectors, the variables don't go into our CSS file after compilation. Developers use them only inside the SASS file to avoid having unnecessary information inside the CSS.
Many might argue that variables already exist in CSS and are similar to what we saw above. And that's right. In CSS, it's now possible to control colors in the same way. But this introduces extra values, and variables are a bit more complicated than it is in preprocessors.
It's also important to understand the difference between variables in SASS and CSS. Variables in CSS exist in real-time. They're in the CSS file, can be changed directly in CSS, and browsers constantly access them when needed. Variables in SASS disappear after compilation, and they're replaced with values in CSS.
Area of visibility
We can declare a variable inside or outside a selector. Depending on where the variable was declared, it can be used either in the whole project or only within a certain selector. Look at an example of this code:
$margin-top: 20px;
.card {
$bg-color: #f9f9f9;
}
.wrapper {
margin-top: $margin-top;
background: $bg-color;
}
In this case, we declared two variables: $margin-top
and $bg-color
. We subsequently use both variables in the .wrapper
selector. What happens after compilation? There won't be any compilation. We'll get an error message:
Error: Undefined variable.
╷
9 │ background: $bg-color;
│ ^^^^^^^^^
╵
The compiler tells us about an unknown variable on line 9. But it's there - we declared it on line 4! Yes - the $bg-color
variable exists in the code, but it only exists inside the .card
selector and is simply invisible outside of the selector.
This behavior is called variable scope. Depending on where we declare a variable, we can access it in the whole project or only within one selector. In this example, the $margin-top
variable is a global variable because we can access it in any part of our SASS file. The $bg-color
variable in the example is a local variable and is only available within the selector where it was defined.
Let's look at another example:
.card {
$main-bg: #f9f9f9;
$header-bg: #2196f3;
.card-header {
background: $header-bg;
}
.card-body {
background: $main-bg;
}
}
Note that the variables $main-bg
and $header-bg
are declared inside the .card
selector. Since the .card-header
and .card-body
selectors are inside the .card
selector, the variables $main-bg
and $header-bg
will be available for these selectors. After compiling, we get the following CSS code:
.card .card-header {
background: #2196f3;
}
.card .card-body {
background: #f9f9f9;
}
Variable naming
As mentioned above, variable names must be unique. This rule helps to prevent possible errors. A global variable and a local variable can have the same name. Let's try adding a global variable to our last example:
$main-bg: #f7f7f7;
.card {
$main-bg: #f9f9f9;
$header-bg: #2196f3;
.card-header {
background: $header-bg;
}
.card-body {
background: $main-bg;
}
}
.wrapper {
background: $main-bg;
}
Note that the variable $main-bg
is declared at the beginning of the SASS file and in the .card
selector. You probably can't tell at a glance which $main-bg
will be used in the project. Let's try to compile this code. There'll be no errors this time:
.card .card-header {
background: #2196f3;
}
.card .card-body {
background: #f9f9f9;
}
.wrapper {
background: #f7f7f7;
}
The $main-bg
variable created inside the .card
selector has nothing to do with the global variable $main-bg
. Even though they can have the same name, it can confuse you. So, we should not use the same name for global and local variables.
Connecting variables from another file
Often, we split SASS styles into several independent files depending on their purpose for convenient organization. For example, we may have the following file structure:
└── scss/
├── config.scss
├── default_variables.scss
└── app.scss
Let us observe this structure. Here we have the main file app.scss, where we want to connect the settings from the config.scss file and the default variable settings from the default_variables.scss file. You can include these files in the app.scss file with the @import
directive by specifying the path to the desired file:
@import "config.scss";
@import "default_variables.scss";
You also don't need to specify an extension when you connect SASS files. The compiler will find the necessary file in the specified directory and plug it in. It means we can rewrite the code a little and not specify an extra extension:
@import "config";
@import "default_variables";
It is important to consider the order in which the files are connected here. When we have conflicting values inside config.scss and default_variables.scss files, we take the last value. The same cascading rule works here as in CSS; styles written later have higher priority.
Default flag
Let's return to the structure of our project. Write the base colors for our project in default_variables.scss:
$primary: #A0D788;
$secondary: #71D0A7;
$third: #CCD47D;
Now, we connected the file to our main styles file and can use these variables. Use the colors in the app.scss:
@import "config";
@import "default_variables";
.card {
background: $primary;
.btn {
background: $secondary;
}
}
After compiling, we get the following CSS code:
.card {
background: #A0D788;
}
.card .btn {
background: #71D0A7;
}
As time passes, our file with variables grows, and we may even use it as a package in many projects (for example, there's a similar file in the Bootstrap framework), but then we suddenly want to change the base color. It is okay, and it happens in nearly all projects.
If we change the color directly in the default_variables.scss file, we get the result we want. But sometimes, this approach doesn't work. If we use such a file as a package in the form of a packet loaded from outside, then if we change the value in the local file, we won't be able to receive updates. Our file is no longer identical to the one on the shared server.
A special flag, !default
, helps to solve this problem. This flag is set after the variable value and tells us to use the default value only if the variable value wasn't previously specified anywhere. Set the !default
flag for our color scheme:
$primary: #A0D788!default;
$secondary: #71D0A7!default;
$third: #CCD47D!default;
Now, if we add the $primary
variable to the config.scss file, its value will be used as the background color for the .card selector:
- config.scss:
$primary: #09D3AC;
- default_variables.scss:
$primary: #A0D788!default;
$secondary: #71D0A7!default;
$third: #CCD47D!default;
- app.scss:
@import "config";
@import "default_variables";
.card {
background: $primary;
.btn {
background: $secondary;
}
}
After compiling this code, we get the following result:
.card {
background: #09D3AC;
}
.card .btn {
background: #71D0A7;
}
Note that the resulting value of $primary
came from the config.scss file, since the default flag in the variable file is !default
.
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.