How to extend/modify (customize) Bootstrap with SASS
Asked Answered
S

5

29

I want to create a website theme based on Bootstrap. I want to extend Bootstrap's default components and change some of them. For this, I would need access to SASS variables that Bootstrap defines so I can override them.

I though of cloning Bootstrap from GitHub and changing it directly, but I heard that's actually not good practice. Could you give me some advice please?

Serve answered 19/8, 2017 at 20:35 Comment(0)
L
75

Update 2022 (Bootstrap 5)

Generally speaking, customizing Bootstrap 5 SASS works the same way as it did in Bootstrap 4. However, some of the maps have changed (and new ones have been added) so you should follow the Bootstrap SASS documentation for details on how to add, remove or modify any of the maps.

Recent comments on this post indicate there's still some confusion about the order of customizations and imports. However, this concept hasn't changed...

"Variable overrides must come after our functions are imported, but before the rest of the imports"

Because of the way SASS variable defaults work, bootstrap ("the rest of the imports") should be imported AFTER any variable customizations/changes. Since your variable changes will not contain the !default flag, your changes will not be overridden by the Bootstrap defaults when bootstrap is imported at the end.

The proof is in the pudding


Here's how to override / customize Bootstrap 4 with SASS...

Overrides and customizations should be kept in a separate custom.scss file that is separate from the Bootstrap SASS source files. This way any changes you make don't impact the Bootstrap source, which makes changes or upgrading Bootstrap later much easier.

1- Consider Bootstrap's SASS folder structure, alongside your custom.scss...

|-- \bootstrap
|   |-- \scss
|   |   |-- \mixins
|   |   |-- \utilities
|   |   |-- bootstrap.scss
|   |   |-- variables.scss
|   |   |-- functions.scss
|   |   |-- ...more bootstrap scss files
|   custom.scss

2- In your custom.scss, import the Bootstrap files that are needed for the overrides. (Usually, this is just variables.scss. In some cases, with more complex cutomizations, you may also need the functions, mixins, and other Bootstrap files.). Make the changes, then @import "bootstrap". It's important to import Bootstrap after the changes...

/* custom.scss */    

/* import the necessary Bootstrap files */
@import "bootstrap/functions";
@import "bootstrap/variables";

/* make changes to the !default Bootstrap variables */    
$body-color: green;
        
/* finally, import Bootstrap to set the changes! */
@import "bootstrap";

2a (optional) - Also, you can extend existing Bootstrap classes after the @import "bootstrap"; to create new custom classes. For example, here is a new .row-dark class that extends (inherits from) the Bootstrap .row class and then add a background-color.

 /* create new custom classes from existing classes */
 .row-dark {
    @extend .row;
    background-color: #333333;
    color: #ffffff;
 } 

3- Compile the SASS (node-sass, gulp-sass, webpack/NPM, etc..). The CSS output will contain the overrides! Don't forget to check the includePaths if your @imports fail. For a full list of variables you can override, see the variables.scss file. There are also these global variables.

Bootstrap SASS Demo on Codeply

In summary, here's how it works:

1_ First, when the custom.scss file is processed using SASS, the !default values are defined in the bootstrap/variables.scss

2_ Next, our custom values are set, which will override any of the variables that had !default values set in bootstrap/variables.scss

3_ Finally, Bootstrap is imported (@import "bootstrap") which enables the SASS processor (A.K.A. compiler) to generate all the appropriate CSS using both the Bootstrap defaults and the custom overrides.

For those that don't know SASS, try this tool that I made.


Also see:
How to get 15 columns in Bootstrap 4 in SASS CSS?
Bootstrap v4 grid sizes / Sass List
Customizing Bootstrap CSS template
Extending Bootstrap 4 and SASS

Legality answered 2/3, 2018 at 13:31 Comment(9)
How do you approach avoiding writing BS classes in HTML? Say I want only custom classes: .title for example could be written in SCSS as .title { @extend .display-3; @extend .text-primary; } But @extend is supposed to be cursed sitepoint.com/avoid-sass-extend so am not sure if this is a good idea? I do not want ANY Bootstrap classes in my HTML.Daphie
What happens if I set $body-color: green; without importing the bootstrap/variables.scss file before it. It wont work?Instauration
Given the file structure, wouldn't it be : @import "bootstrap/scss/functions"; @import "bootstrap/scss/variables"; @import "bootstrap/scss/bootstrap"; ?Imena
@Imena No it depends. Those are relative paths so they are relative to however bootstrap is included/installed in your SASS compiler.Legality
Please see that this is almost correct, but the imports (of things like variables, functions, etc.) must come AFTER the setting of the overrides if using Bootstrap 4. github.com/twbs/bootstrap-npm-starter/issues/43Cuprum
No, because if you need to reference an existing variable you must import the variables first. What you're saying only works IF you don't need to reference/use another bootstrap variable. This is widely documented as the correct method for both Bootstrap 4 & 5 getbootstrap.com/docs/5.1/customize/sass/#importingLegality
This is not a solution because all this does is override the stuff in the bootstrap files. This happens because "@import bootstrap" just reimports the same files over again and overrides it. I do not believe this is the way the utilities API is supposed to work.Grantland
@Grantland - no, @import bootstrap doesn't override any prior overrides/changes .. read how SASS variable defaults work. When you remove the !default flag in your customizations the variable gets set and subsequent !default flags (as set in bootstrap) will not override the changes., "Variable overrides must come after our functions are imported, but before the rest of the imports."Legality
@extend comes with major performance implications and shouldn't be usedGastro
P
5

I will explain from scratch: Download Ruby because sass is written in Ruby. Open the “start command prompt with Ruby” and enter this:

gem install sass

In macos, ruby is already installed. so in terminal:

sudo gem install sass

If you did install bootstrap through package manager; write this code into main.scss

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

then navigate to your work directory where you keep your main.scss or main.css files. Enter this code into command line:

sass main.scss main.css

this will initialize compiling sass to css.

If you did download bootstrap source files, find the “scss” folder in your source folder

BOOTSTRAP\bootstrap-4.2.1\bootstrap-4.2.1\scss

and copy it into your style folder in your project where u keep all styling files:css,scss,bootstrap then import “bootstrap.scss” file into main.scss

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

And now initialize compiling by entering this code:

sass main.scss main.css

Finally, you can type:

sass --watch main.scss:main.css //this should be running

to watch all changes in main.css DONT FORGET: You will write your css codes into main.scss, sass will compile it to main.css and you will LINK main.css file in your html.

If you are using visual studio code, you can install “Live Sass Compiler” extension and down below you will see “Watch Sass” button. create main.scss file in the style folder and after import the files the way I explained above, click on the “watch Sass” button and it will start compiling.

Now in bootstrap folder, under scss folder there is _variables.scss folder. this contains bootstrap variables. let's say you wanna change border-radius. in main.scss file, before importing your bootstrap:

$border-radius:10rem
@import "./scss/bootstrap.scss";
Password answered 18/5, 2019 at 23:26 Comment(0)
S
2

It took me a bit to piece together an adequate tutorial to install and use sass with homebrew to edit bootstrap 4 in a node/express project.

Install sass using homebrew

brew install sass/sass/sass

Install bootstrap in your project

npm install bootstrap --save

Change to assets dir, create sass directory, create app and custom file

cd public/assets/css && mkdir sass && touch sass/app.scss sass/custom.scss

In app.scss add the following

// import bootstrap files
@import "../../../../node_modules/bootstrap/scss/functions";
// import bootstrap defaults
@import "../../../../node_modules/bootstrap/scss/variables";
// import customization
@import "custom.scss";
// finally, import Bootstrap to set the changes!
@import "../../../../node_modules/bootstrap/scss/bootstrap";

In custom.scss add a sample customization

$hotness: #fb3f7c;
$link-color: $hotness;

Run sass; automatically export/update .css file

sass --watch sass/app.scss sass/bootstrap.css

Link to the new bootstrap file in your html

References

Synopsize answered 4/7, 2020 at 11:23 Comment(0)
R
1

Github version of Bootstrap always changes since the foundation itself is being updated constantly. Not to mention, the way Bootstrap is structured, it doesn't necessarily compile the way your SASS compiler will export. The best practice is to structure it the way best suitable for you.

Here's how I usually structure my entire project

/style/
/style/theme.scss
/style/theme.min.css
/style/bootstrap.scss
/style/bootstrap.min.css
/style/bootstrap/{subfiles}
/style/bootstrap/mixins/{subfiles}
/style/bootstrap/utilities/{subfiles}

/scripts/
/scripts/bootstrap.min.js
/scripts/main.min.js
/scripts/bootstrap/

This assumes you have sass and js minifier.

Risteau answered 19/8, 2017 at 22:24 Comment(0)
F
0

First of all install SASS, you can check which one fits you the most in https://sass-lang.com/install/ Then SASS will help you to compile your scss files to css files.

To watch compiled files type to cli sass --watch input.scss output.css

To compile scss file and add to css file type to cli sass input.scss:output.css

or compile scss file and add to css file and exclude .map files that are added type to cli sass input.scss:output.css --no-source-map

You will need bootstrap-scss files, if you using node then when downloaded bootstrap through npm, this folder should exist in your node modules, but if you downloaded and attached for example bootstrap.min.css then you will need to download this folder seperately. You can find it here:https://github.com/crissdev/bootstrap-scss

Do not override files in bootstrap-scss package, it is not the best practice. If letter on you will update the version, then all your customization will be lost and it is very hard to maintain it.

My Folders/ Files tree of bootstrap in app after downloads:

extras- 
    bootstrap-
           bootstrap-scss
           bootstrap.bundle.min.js
           bootstrap.min.css       
    
    scss-
           custom.scss

In html file, for instance index.html only add: bootstrap.min.css , index.css and bootstrap.bundle.min.js files for bootstrap to work. Do not include custom.scss file or bootstrap-scss folder.

For my scss to be applied I had to play a little bit with imports in custom.scss file. A structure of imports is very important, I have followed the import structure from my downloaded bootstrap/bootstrap-scss/bootstrap file that imports everything. I have added all imports from that file and deleted the ones that was not needed (my scss was applied without them). If you want to add all imports then just add properties or variables that you want to change/update and below them import bootstrap/bootstrap-scss/bootstrap file. For instance:

    $body-color: #121dea;
    $primary: orange;
    #nav {
        position: sticky;
        top:0px;    
     }
    @import "../bootstrap/bootstrap-scss/bootstrap";

Or you could import just the ones that you need. For instance I had to add all these imports in order to be able to see that my scss was applied.

    // /functions must be applied first before updating or changing properties/variables etc...
    @import "../bootstrap/bootstrap-scss/functions";
    
    $body-color: #121dea;
    $primary: orange;
    #nav {
        position: sticky;
        top:0px;    
        
    }
    @import "../bootstrap/bootstrap-scss/variables";
    //doesnt have to have var dark if not used
    //@import "../bootstrap/bootstrap-scss/variables-dark";
    @import "../bootstrap/bootstrap-scss/maps";
    @import "../bootstrap/bootstrap-scss/mixins";
    @import "../bootstrap/bootstrap-scss/utilities";
    @import "../bootstrap/bootstrap-scss/root";
    @import "../bootstrap/bootstrap-scss/reboot";
    //if wanted to add any more imports, they must be applied after /reboot and before /utilities/api, at least in my case.
    // For instance /nav import must be here if in use... 
    //@import "../bootstrap/bootstrap-scss/nav";
    @import "../bootstrap/bootstrap-scss/utilities/api";

Have a look at the official site for more info about how to change, update variables, properties etc... they are explaining it well in here : https://sass-lang.com/guide/

Also a specificity is very important when want to override your css. For example lets say you had a nav element with a position:static in bootstrap files and wanted to change it to sticky, then you might need to add in scss file that element more specificly, perhaps

div .div-class nav .navbar {
    position:sticky; 
    top: 0px
}

or you might add an id to that element, to be able to get better specificity

#nav-id {
   position:sticky;
   top: 0px
}

I hope it will help someone.

For answered 5/3 at 6:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.