In any programming language, scoping should be considered when setting variables. In Sass, all variables declared outside of a mixin or function will have a global scope and can be referenced in any Sass selector that uses the variable.
$text-color: blue;
html {
font-family: Arial, sans-serfi;
font-size: 1em;
color: $text-color;
}
Keeping true to the Cascading part of CSS, currently if the value of the variable is changed, all further reference to the variable will be updated to the new value. This sounds logical but consider the following example:
// I instantiated the $text-color variable to Blue
$text-color: blue;
// Here, the intent was to change the color for the .error style
.error {
$text-color: red;
color: $text-color;
}
// Following the cascade, in .normal-text, I want Blue, but get Red.
.normal-text {
color: $text-color;
}
The above Sass will compile to the following CSS:
.error {
color: red;
}
.normal-text {
color: red;
}
As you can see, the variable $text-color
has a global scope and it is set to blue
. However when I changed the $text-color
variable to red
, you will see that all further instances of $text-color
variable will be red
. This is common pitfall among novice Sass users. The best way to prevent this pitfall is to follow these guidelines:
!default
flagWhen setting variables in mixins or functions, keep the above scoping scenario in mind. If there is a variable that needs to be scoped within a mixin or function, declare it within the required scope. Consider the following:
@mixin add-border($border-position: all, $border-size: 1px,
$border-pattern: solid, $border-color: black) {
$border-position-all: all;
@if $border-position == $border-position-all {
border: $border-size $border-pattern $border-color;
}
@else {
border-#{$border-position}: $border-size
$border-pattern $border-color;
}
}
block {
@include add-border();
}
In this example, we set a local variable border-position-all: all
. We could also write the mixin as such:
$border-position-all: all !default;
@mixin add-border(
$border-position: $border-position-all, $border-size: 1px,
$border-pattern: solid, $border-color: black) {
@if $border-position == $border-position-all {
border: $border-size $border-pattern $border-color;
}
@else {
border-#{$border-position}: $border-size
$border-pattern $border-color;
}
}
Setting the border-position-all
as a global variable, it can now be referenced throughout the application. The other difference here is that the $border-position-all
variable uses the !default
flag.
As you can looking at our $border-postion
variable declaration, we have used a flag called !default
. There are two flags that can be set when declaring a variable:
!default
!global
In the next section, we will take a closer look at how these flags work and how we can take advantage of them.