Search code examples
variablesimportsassdefault

Sass: Overriding default variables of imported stylesheets


Problem

About overriding !default variables -- I have two .sass files:

main.sass

$variable: black

@import "_another_import.sass"
@import "_import.sass"

_import.sass

$variable: blue !default

body
    background: $variable

The $variable resolves to blue in the compiled CSS:

body {
    background: blue;
}

However, if I specify the overriding variable value right before I import the _import.sass stylesheet, Sass compiles it to black:

main.sass

@import "_another_import.sass"

$variable: black

@import "_import.sass"

Question

Is this behavior intended? Is there a way to declare overrides for !default variable values earlier than the !default values are declared in imports (maybe even in a separate file)?


Actual setup (for reference)

My actual setup is a little bit more complicated than that. I am using Myg (NPM components) with myg-rails (generating file structure to customize variables) and Webpack. So I have a myg.sass file loading _variables.sass and _myg.sass. _variables.sass loads a couple of other files which define the variables. _myg.sass imports the Myg (NPM) components. I verified that when I define a variable in _variables.sass and use it + set a default in a Myg component, the default will override the already set value.


Solution

  • No, what you are doing should work. The resulting behavior you're experiencing is irregular and not intended.

    From sass-lang docs:

    You can assign to variables if they aren't already assigned by adding the !default flag to the end of the value. This means that if the variable has already been assigned to, it won't be re-assigned, but if it doesn't have a value yet, it will be given one.

    I suspect there may be something else at play that we need to investigate.

    I've verified the correct behavior with these files:

    Sass source:

    _t1.sass

    div
        margin: 0
    

    _t2.sass

    $c: blue !default
    
    body
        background: $c
    

    main.sass

    $c: black
    
    @import '_t1.sass'
    @import '_t2.sass'
    

    CSS result:

    div {
      margin: 0;
    }
    
    body {
      background: black;
    }
    

    It is black as intended.