I'm rolling out my own bootstrap-sass customization in a pretty big project. In my git repo I have my own application.scss
file which mirrors the original bootstrap.scss
, removing what I don't need and adding my own custom variables, mixins and styles.
I cannot understand the right way to do this while retaining a DRY approach. Should I @import 'application/variables';
before or after I @import 'path/to/bootstrap/variables';
?
The before approach
This seems to be the preferred way for bootstrap developers, because all the variables declared in _variables.scss
are followed by the !default
flag, which takes action only if the variable has been previously declared.
Where does this fail? Take for example a declaration like this:
$brand-primary: $gray;
Compiling this SASS code will spit out an undeclared variable
error, because $gray
is defined in bootstrap's _variables.scss
, which is imported later. If I want this to work, I'll have to re-declare $gray
at the top of my file, even though it didn't change from the default.
This may not sound like a big deal, but over a certain level of complexity it starts to happen quite a lot, and your application/_variables.scss
goes from being "the file where I define my own variables" to "the file where I define my variables and copy over some other bootstrap stuff without actually changing it".
The after approach
To overcome the problem of the before approach I tried to import my variables after bootstrap's ones. It turns out it doesn't really work either, and it's broken in subtler ways. Look at this example:
$padding-base-vertical: 8px;
Looks innocent, right? And in fact it will change the vertical padding as needed. How does this break? It breaks, for example, the $input-height-base
variable, declared later in bootstrap's _variables.scss
, which is not correctly recalculated based on $padding-base-vertical
's changes.
And this is how $input-height-base
is defined:
$input-height-base: ($line-height-computed + ($padding-base-vertical * 2) + 2) !default;
Thus $input-height-base
is calculated with $padding-base-vertical
's default value and then never again. As a side effect, this kind of problem is quite hard to debug (at least it was for me).
The "solution"? Redeclare $input-height-base
and all the other dependent variables in application/_variables.scss
just like they are in bootstrap. Yes, it's the same workaround of the after approach.
So, is there a DRY way to do this? I can't even split my variables in two, part to set before and part to set after, because I could bump in a variable which hits both problems.
The first approach is the less ugly, but it's far from being an ideal solution.