Bootstrap-Sass: Overriting Variables with using other Variable
The only solution I've seen is to declare the variables that you depend on. So, in bootstrap-sass's _variables.scss
, you find the line $grid-gutter-width: 30px !default;
and use it in your own file like so:
$grid-gutter-width: 30px;
$container-desktop: (940px + $grid-gutter-width);
As you're imagining, it's unfortunate to just copy information like that, especially if you end up having to copy several variable definitions just to declare the one you actually want. I too would be very interested if someone has a solution that's more "DRY".
Bootstrap SASS variable override challenge
Solved, but I don’t know from which version this works. I believe the solution could have always been available. Tested on:
> sassc --version
sassc: 3.2.1
libsass: 3.2.5
sass2scss: 1.0.3
We are going to use a simplified environment, so filenames do not match with Bootstrap’s.
Challenge
Given a framework we do not control (for example installed only on the Continuous Integration environment and not available in our machines) that expresses SCSS variables in the following manner:
// bootstrap/_variables.scss
$brand-primary: #f00 !default;
$brand-warning: #f50 !default;
$link-color: $brand-primary !default;
And given a file in that same framework that uses the variables:
// bootstrap/main.scss
a:link, a:visited {
color: $link-color;
}
The challenge is:
Include the framework in your own application’s SCSS in such a way that
- variables’ dependencies in the framework are preserved and honors;
- you can depend in on the default values but still be able to change the results on the framework dependencies.
More precisely:
Include the framework in your application’s SCSS in such a way that
$brand-color
will always be the inverse of$brand-warning
, whatever its value is in the framework.
Solution
The main file would look like this:
// application.scss
@import "variables";
@import "bootstrap/variables";
@import "bootstrap/main";
And your variables file would look like this:
// _variables.scss
%scope {
@import "bootstrap/variables";
$brand-primary: invert($brand-warning) !global;
}
Results:
> sassc main.scss
a {
color: blue; }
Explanation
The %scope
part is not something magic of SCSS, it’s simply a hidden class with the name scope
, available exclusively for later extensions with @extend
. We are using it just to create a variable scope (hence the name).
Inside the scope we @import
the framework’s variables. Because at this moment there’s no value for each variable every variable is created and assigned its !default
value.
But here’s the gimmick. The variables are not global, but local. We can access them but they are not going to pollute the global scope, the one that will be later used to derive variables inside the framework.
In fact, when we want to define our variables, we want them global, and indeed we use the !global
keyword to signal SCSS to store them in the global scope.
Caveats
There’s one major caveat: you cannot use your own variables while you define them.
That means that in this file
%scope {
@import "bootstrap/variables";
$brand-primary: black !global;
@debug $brand-primary;
}
The @debug
statement will print the default value defined in bootstrap/_variables.scss, not black
.
Solution
Split variables in two parts:
%scope {
@import "bootstrap/variables";
$brand-primary: black !global;
@debug $brand-primary;
}
@debug $brand-primary;
The second @debug
will indeed correctly print black
.
Conditially override scss variables for bootstrap 4 theme switching
This was the solution I went with:
// Default theme
$body-bg: #fff;
// etc...
// Bootstrap and its default variables
@import "node_modules/bootstrap/scss/bootstrap";
// dark theme, turned on by adding class dark to document.documentElement (html tag)
.dark {
$body-bg: #000;
// etc...
// Import just the things you customize
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/mixins";
@import "~bootstrap/scss/tables";
@import "~bootstrap/scss/button-group"
// etc....
}
Bootstrap 4 how to overwrite scss variables that are used to define other default variables
Separate the override variables....
The only overrides that need to follow the /variables
import are those that reference variables (ie: $secondary: $gray-400;
).
If you just want to override a variable that doesn't reference another (ie: $font-size-base: 2.9rem;
) that would go before the /variables
import...
/* simple overrides */
$font-size-base: 2.9rem;
@import "bootstrap/functions";
@import "bootstrap/variables";
/* var dependent overrides */
$theme-colors: (
secondary: $gray-400
);
@import "bootstrap";
https://www.codeply.com/go/wpc3XKQ8TG
Note: To override a theme color such as secondary
you must update the theme-colors map.
Related Topics
Jquery-Ui Datepicker CSS Problem
Start Div Scrollbar from Bottom with Pure CSS
Why Does Fixed Positioning Alter the Width of an Element
Jw Player: Cross-Browser "Display:None" Player Behavior
Cutting a Triangle Out of Div, But Have It Horizontally Centered
CSS Display Property When a Float Is Applied
Shape-Outside of an Image Centered Between Two Text Blocks
Percentage Height in Nested Flex Box
Does a Cache Buster on an Image Url in CSS Cause an Extra Request
Media Query for iPad (Landscape) Applied to Samsung Galaxy Tab 2 (Landscape) as Well
Fluid Navigation Items of Different Widths with Equidistant Spacing
Make Video Fit 100% with Any Screen Resolution
CSS 3D Transforms Works at Random in Chrome 16
How to Line Up 3 Divs on The Same Row
Jekyll Syntax Highlighting Not Working - Classes Are Not Being Added