Normally when you assign a value to a variable, if that variable already had a value, its old value is overwritten.
Default Values
But if you're writing a Sass library, you might want to allow your users to configure your library's variables before you use them to generate CSS.
To make this possible, Sass provides the !default flag. This assigns a value to a variable only if that variable isn't defined or its value is null. Otherwise, the existing value will be used.
How !default works
| Scenario | Variable state before | Assignment | Final value |
|---|---|---|---|
| Not defined | $foo: bar !default; |
bar |
|
| Already defined | $foo: baz; |
$foo: bar !default; |
baz (keeps existing) |
Defined as null |
$foo: null; |
$foo: bar !default; |
bar (null is treated as undefined) |
$width: 100px;
$width: 200px !default; // Keeps 100px
$height: null;
$height: 50px !default; // Becomes 50px
$color: blue !default; // Becomes blueConfiguring Modules
Variables defined with !default can be configured when loading a module with the @use rule. Sass libraries often use !default variables to allow their users to configure the library's CSS.
To load a module with configuration, write @use <url> with (<variable>: <value>, <variable>: <value>). The configured values will override the variables' default values. Only variables written at the top level of the stylesheet with a !default flag can be configured.
// _library.scss
$black: #000 !default;
$border-radius: 0.25rem !default;
$box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default;
code {
border-radius: $border-radius;
box-shadow: $box-shadow;
}// style.scss
@use 'library' with (
$black: #222,
$border-radius: 0.1rem
);The compiled CSS uses the user's overrides:
code {
border-radius: 0.1rem;
box-shadow: 0 0.5rem 1rem rgba(#222, 0.15);
}Library pattern: _variables.scss
A common convention in Sass libraries is to place all configurable variables in a dedicated partial, then import it first so users can override them before any CSS is generated:
// _variables.scss
$primary-color: #036 !default;
$font-stack: Helvetica, Arial, sans-serif !default;
$base-spacing: 1rem !default;// _components.scss
@use 'variables';
.button {
background-color: variables.$primary-color;
font-family: variables.$font-stack;
padding: variables.$base-spacing;
}// user-style.scss
@use 'variables' with (
$primary-color: purple,
$font-stack: Georgia, serif
);
@use 'components';!default with @forward
When you @forward a module, its !default variables can still be configured by downstream users, as long as they are defined at the top level of the forwarded file:
// _library.scss
$spacing: 1rem !default;// _index.scss
@forward 'library';// user-style.scss
@use 'index' with ($spacing: 2rem);Summary
!defaultassigns a value only if the variable is undefined ornull.- Use
!defaultfor library variables that users should be able to override. - Configure
!defaultvariables with@use <url> with (<var>: <value>, ...). - Only top-level variables with
!defaultcan be configured via@use ... with. - Common pattern: put
!defaultvariables in a dedicated partial and import it first.