_variables.scss // Bootstrap's core _app-variables.scss // App base _client-variables.scss // Client-specific
$brand: blue; $text: $brand;
Now, let's say the above variables are defined in _variables.scss. Then let's say in _app-variables.scss, I override only the $brand variable to make it red:
$brand: red. Since SASS interprets the code line by line sequentially, it will first set $brand to blue, then it will set $text to blue (because $brand is blue at that point), and finally it will set $brand to red. So the end result is that changing $brand afterwards does not affect any variables that were based on the old value of $brand:
_variables.scss --------------------- $brand: blue; $text: $brand; // $text = blue . . . _app-variables.scss --------------------- $brand: red; // this does not affect $text, b/c $text was already set to blue above.
But obviously that's not what I want - I want my change of $brand to affect everything that depends on it. In order to properly override variables, I'm currently just making a full copy of _variables.scss into _app-variables.scss, and then making modifications within _app-variables from that point. And similarly I'm making a full copy of _app-variables.scss into _client-variables.scss and then making modifications within _client-variables.scss at that point. Obviously this is less than ideal (understatement) from a maintenance point of view - everytime I make a modification to _variables.scss (in the case of a Bootstrap upgrade) or _app-variables.scss, I have to manual trickle the changes down the file override stack. And plus I'm having to redeclare a ton of variables that I may not even be overriding.
I found out that LESS has what they call "lazy loading" (http://lesscss.org/features/#variables-feature-lazy-loading), where the last definition of a variable is used everywhere, even before the last definition. I believe this would solve my problem. But does anyone know a proper variable-override solution using SASS?
Here's one technique I've already thought through: include the files in reverse order, using
!default for all variables (this technique was also suggested in the answer to this question). So here's how this would play out:
_app-variables.scss --------------------- $brand: red !default; // $brand is set to red here, overriding _variables.scss's blue. . . . _variables.scss --------------------- $brand: blue !default; // brand already set in _app-variables.scss, so not overridden here. $text: $brand !default; // $text = red (desired behavior)
So that solution is almost perfect. However, now in my override files, I don't have access to variables defined in Bootstrap's _variables.scss, which I would need if I wanted to define my variable overrides (or my own additional custom variables) using other Bootstrap variables. For example, I might want to do:
$custom-var: $grid-gutter-width / 2;