How to override boostrap variables in sass?

I’m using latest sass version.

When I put my variables before boostrap, gives me errors like
$gray-lighter is not defined

If I put my variables after boostrap they don’t work.

Should I split my sass in two?

like, put variables before bootstrap and other modifications after it?

@import "common/_variables";
@import "_myvariables";
// bower:scss
@import "../../bower_components/bootstrap-sass-official/assets/stylesheets/_bootstrap.scss";
// endbower
1 Like

https://github.com/roots/sage/blob/master/assets/styles/common/_variables.scss

This worked:

  1. Override Boostrap variables BEFORE calling _boostrap.scss
  2. Use my own sass AFTER _boostrap.scss

So my variables and bootstrap combine and then become available to my other styles.

Variables in SASS can’t be used until declared.

I think this info could help somebody:

@import "common/_variables"; //override boostrap variables

// bower:scss
@import "../../bower_components/bootstrap-sass-official/assets/stylesheets/_bootstrap.scss";
// endbower

@import "sinetiks"; //here I can use all boostrap variables
2 Likes

_variables.scss is in a different order in the SASS version than the LESS verion. In LESS, Bootstrap loads its variables and LESS, then the _variables override is used.

In SASS, _variables.scss is loaded before you get to bootstrap. This works if you are assigning values, but doesn’t work if you are referencing other variables like $grey-light or $font-family-base.

Brand new to SASS, so not sure why the difference in file order. Couldn’t _variables.scss load right before _global.scss?

Yeah, I’m “struggling” with this too right now.

I simply want to override $headings-color (default is inherit) with $brand-primary (or $gray-dark or anything else defined in bootstrap\_variables). $brand-primary isn’t defined yet, so it causes an error. If I move the common\_variables below the wiredep bootstrap entry in main.scss then the change doesn’t take. Not sure why… Is it that you can only declare a variable once? So does that mean that I need to define $brand-primary again in common\_variables even if its not changing?

This happened to me when sage migrated to sass.

Solved it like this:
https://discourse.roots.io/t/how-to-override-boostrap-variables-in-sass?source_topic_id=3729

This did not work for me.

Is there a naming convention for the .scss to override common/ _variables.scss?

This is frustrating as hell. Variables are only recognised when included directly at the top of any given custom .scss file. This functioned flawlessly in .less version…

Has this been sorted out yet??

There’s not really anything to sort out.

LESS only assigns values to variables at the last moment, creating a ‘last definition wins’ scenario. This means that you can define a variable after it has been used and it will still work.

SCSS doesn’t follow the same methodology so all variables have to be defined before you reference it.

1 Like

So assigning a new variable a value in common/_variables.scss and importing it before bootstrap.scss should work then? I want to create new variables not reassign bootstrap’s but my variables are never recognized when I create them there…

In what file should I assign my variables so that they are defined before I reference them?

I’m trying to use them in a custom sheet styles/home-page.scss.

Thanks in advanced! This is driving me batty.

1 Like

yes How to override boostrap variables in sass? - #3 by lalo

1 Like

Thanks, Lalo, for directing my attention back to the same thread that I am already on.

In the end, the problem was that I had created my custom style sheets in styles/ as per the $10 video instructions and they were obviously compiling before the common/_variables.scss. Thus, my sheets were tying to use variables that had not been assigned yet.

Since changing to sass, the video instructions are no longer valid. I have moved my custom files into layout/, imported them into main.scss, and now it works.

Late to the party, but this might be helpful in case others come upon it like me.

Good explanation of the order to import & override here here:
https://laracasts.com/discuss/channels/elixir/how-to-modify-things-inside-bootstrap-sass

Per discussion @lindstrom:

  1. Bring your _variables.scss in first. The variables are defined with !default in the bootstrap _variables.scss file which means to use their value unless the value has already been defined.

  2. Bring in bootstrap

  3. Next mixins - prioritize your overwrites before other components that depend on them that you want to overwrite.

  4. Next overwrites (like navbar, buttons, alerts, etc)

  5. Finally, your own styles

1 Like

My issue is this:
I want to override bootstrap’s $container-large-desktop variable which is defined as:

$container-large-desktop:      (1140px + $grid-gutter-width) !default;

So I can’t simply set it as:

$container-large-desktop:      (1500px + $grid-gutter-width);

in common/_variables.scss because $grid-gutter-width is not yet defined.

So far my only solution is copy the dependency definitions into my _variables.scss whenever I do something like that.

Would there be a better approach?

I think your solution is fine, in fact I believe it’s the intended way to go about things.

I copy huge chunks of the Bootstrap default variable definitions into my own variables file at the start of every project. By doing this I can get a base configuration set up really quickly. It saves a ton of time.

I found the best solution to be adding a watch task for bower_components/bootstrap/scss in the gulpfile. No idea why it’s not there in the first place:

In the gulpfile before line 245 (the task that watched the styles folder) add this task which will implement changes done to _custom.scss:
gulp.watch(['bower_components/bootstrap/scss/**/*'], ['styles']);

It worked for me.

Do you make your custom settings in bower_components/bootstrap/scss/custom.scss? If so, they will be overwritten if you update the package or if you do a clean install of your theme. The Bower folder is also .gitignored by default (and should be kept that way IMHO) so you wont have your settings in the repo if you have one.

I realised that after posting. Perhaps the best way could be to copy the relevant core bootstrap scss files from the bower_components folder into your assets/styles directory. I find it better trying to harness using the rules outlined in the framework as opposed to recreating the wheel by defining variables for fonts sizes etc that have already been done. Still bugs me that the end result is still a stylesheet with tons of core bootstrap overwritten rules. Shoudln’t base changes like fonts, spacings etc be done at bootstrap core level? According to documentation for bootstrap, we suppose to copy variables and other custom stuff into the bootstraps _custom.scss. But you are right, bower folder shouldn’t be touched. Another solution could be creating a task in the gulpfile that replaces the BS _variables.scss with your own which would reside in your style directory.

I use the solution mentioned above, have my own _bootstrap-variables.scss (or whatever you want to call it) imported before the original Bootstrap SASS files.

Simple and powerful :slight_smile:

Awesome… Would you mind dropping your code here with small step process on how you did it?

I always just copy the Bootstrap default variables (and any variables those rely on) I need to override into Sage’s _variables.scss and then change them. It’s always fewer than the total number of variables and doesn’t involve manipulating a dependency.