3

What is the best way to override variables?

I found the following order works:

@import "bootstrap/_functions.scss";

$primary: red;

@import "bootstrap/_variables.scss";
@import "bootstrap/_mixins.scss";

But what if I want to use a variable from Bootstrap? For example:

@import "bootstrap/_functions.scss";

$primary: $red;

@import "bootstrap/_variables.scss";
@import "bootstrap/_mixins.scss";

This doesn't compile because the $red variable isn't defined.

I've tried this order:

@import "bootstrap/_functions.scss";    
@import "bootstrap/_variables.scss";
@import "bootstrap/_mixins.scss";

$primary: $red;

Which works but only for some elements. For example bootstap/_variables.scss includes:

$link-color: $primary !default;

The $link-colour variable doesn't use the override and instead uses the default value.

Any ideas?

DisgruntledGoat
  • 70,219
  • 68
  • 205
  • 290
user2246968
  • 119
  • 3
  • 11

2 Answers2

1

I normally use a structure like below, /src/scss/core is my custom sass directory:

// 1. Include functions first (so you can manipulate colors, SVGs, calc, etc)
@import "../../node_modules/bootstrap/scss/functions";
@import "../../node_modules/bootstrap/scss/variables";

// 2. Include any default variable overrides here
@import "core/variables"; // Custom theme variables
@import "core/variables-bootstrap"; // Bootstrap variables overrides

// Mixins
@import "../../node_modules/bootstrap/scss/mixins";
@import "core/mixins.scss";

// Bootstrap core
@import "../../node_modules/bootstrap/scss/utilities";
@import "../../node_modules/bootstrap/scss/root";
@import "../../node_modules/bootstrap/scss/reboot";
@import "../../node_modules/bootstrap/scss/type";
@import "../../node_modules/bootstrap/scss/images";
@import "../../node_modules/bootstrap/scss/containers";
@import "../../node_modules/bootstrap/scss/grid";
@import "../../node_modules/bootstrap/scss/tables";
@import "../../node_modules/bootstrap/scss/forms";
@import "../../node_modules/bootstrap/scss/buttons";
@import "../../node_modules/bootstrap/scss/transitions";
@import "../../node_modules/bootstrap/scss/dropdown";
@import "../../node_modules/bootstrap/scss/button-group";
@import "../../node_modules/bootstrap/scss/nav";
@import "../../node_modules/bootstrap/scss/navbar";
@import "../../node_modules/bootstrap/scss/card";
@import "../../node_modules/bootstrap/scss/accordion";
@import "../../node_modules/bootstrap/scss/breadcrumb";
@import "../../node_modules/bootstrap/scss/pagination";
@import "../../node_modules/bootstrap/scss/badge";
@import "../../node_modules/bootstrap/scss/alert";
@import "../../node_modules/bootstrap/scss/progress";
@import "../../node_modules/bootstrap/scss/list-group";
@import "../../node_modules/bootstrap/scss/close";
@import "../../node_modules/bootstrap/scss/toasts";
@import "../../node_modules/bootstrap/scss/modal";
@import "../../node_modules/bootstrap/scss/tooltip";
@import "../../node_modules/bootstrap/scss/popover";
@import "../../node_modules/bootstrap/scss/carousel";
@import "../../node_modules/bootstrap/scss/spinners";
@import "../../node_modules/bootstrap/scss/offcanvas";
@import "../../node_modules/bootstrap/scss/placeholders";

// Helpers
@import "../../node_modules/bootstrap/scss/helpers";

// Utilities
@import "../../node_modules/bootstrap/scss/utilities/api";

This structure works for me with variable overrides/extending but like Zim said you'd need to override $link-hover-color too since it's default value is set before you defined your custom $primary colour (at least that's my understanding of the !default flag).

$primary: $red;
$link-color: $primary;
$link-hover-color: shift-color($link-color, $link-shade-percentage);
Tom James
  • 184
  • 1
  • 3
  • This is what worked for me. Another advantage with this style is you can comment out components that you don't use to reduce the size of the CSS bundle. – DisgruntledGoat Apr 10 '23 at 18:08
0

Bootstrap 5

I think you'd have to set any other vars that use $link-color (ie: $btn-link-color) and merge the new colors into the $theme-colors map...

@import "functions";
@import "variables";
@import "mixins";

$primary: $red;
$link-color: $primary;
$btn-link-color: $primary;

$theme-colors: map-merge(
  $theme-colors,
  (
    "primary": $primary
  )
);

@import "bootstrap";

Demo

Carol Skelly
  • 351,302
  • 90
  • 710
  • 624
  • Thanks. I've tried this but it still doesn't work well. If you hover over the link, you can see that it's blue. So the variable $link-hover-color is using the original $primary variable and not the override. – user2246968 Feb 03 '21 at 15:01
  • So just change $link-hover-color too – Carol Skelly May 12 '21 at 13:46