Bootstrap-Sass: Overriting Variables with Using Other Variable

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

  1. variables’ dependencies in the framework are preserved and honors;
  2. 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



Leave a reply



Submit