# Bootstrap Sass

  • Now that we know (the basics of) Bootstrap and Sass, we can combine the best of both worlds and start using Bootstrap in a more advanced way

# Project set-up

# GitHub repository

  • Start by cloning (or downloading) the sass-bs-example (opens new window) repository from GitHub
    • If you use git clone ..., you can safely delete the .git folder (as you are no collaborator on this repo)
  • The folder structure of this project is similar to the structure of the previous examples: the Sass code is stored in the folder scss, while the dist folder contains all files (HTML, CSS and JS) for production

# npm install

  • When you open this project in PhpStorm, the following pop-up appears at the bottom right of your IDE:
    Npm install pop-up
    • Either click on Run 'npm install' or type the command npm install (or npm i) in a terminal
  • This command installs the required Node packages (specified under "devDependencies" in package.json) in a folder node_modules
    • Besides the package bootstrap, several other packages (browser-sync, gulp-sass, ...) needed for the Gulp-based workflow (see below) are installed


 
 
 
 
 
 
 
 
 
 
 
 


{
  ...
  "devDependencies": {
    "bootstrap": "^5.2.3",
    "browser-sync": "^2.27.11",
    "gulp": "^4.0.2",
    "gulp-autoprefixer": "^8.0.0",
    "gulp-css-mqpacker": "^1.0.1",
    "gulp-dart-sass": "^1.0.2",
    "gulp-newer": "^1.4.0",
    "gulp-notify": "^4.0.0",
    "gulp-plumber": "^1.2.1",
    "gulp-sourcemaps": "^3.0.0"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

REMARK

More background information (on npm install, dependencies, ...) can be found on the course page Tools > npm

# Bootstrap source code

BS Source code - folders

  • In the file bootstrap.scss all partials (in the map scss) are imported
    • The partials in the subfolders are imported via the partials _mixins.scss (everything from the folders mixins and vendor) and _utilities.scss (everything from the folder utilities)
    • Of course, the order of these imports is important: variables and mixins have to be known before you can use them, ...

BS Source code - files

REMARK: Bootstrap GitHub repo

As you can see (in README.md), the Bootstrap source code originates from a repository on GitHub (https://github.com/twbs/bootstrap/ (opens new window)) with more than 1300 contributors and 22000 commits GitHub

WARNING

Do NOT change anything in Bootstrap's source code (bootstrap.scss, partials, ...).
All changes that are necessary to meet the wishes of your client should be done in other files (that refer to the original source code), as explained below. Anyone who deviates from this will have major problems (i.e. you will lose your changes) during an update of the framework!

# Gulp workflow

  • We will automate your previous workflow (based on live-server and sass compilation) even further
  • We will use Gulp, which is a task manager to automate repeated tasks in your workflow
  • All Gulp configurations are stored in gulpfile.js:
...
// Copy Bootstrap JS-files
gulp.task('copy-js', () => {...
});

// Compile sass into CSS (/dist/css/) 
gulp.task('sass', () => {...
});

// Live-reload the browser
gulp.task('browser-sync', () => {...
});

gulp.task('default', gulp.series('copy-js', 'sass', 'browser-sync'));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  • In this file, 4 tasks are defined:
    • a task sass that compiles the Sass code in scss/style.scss to dist/css/style.css (the file which is linked to in dist/index.html)
      • The resulting CSS file will include the complete (potentially modified) Bootstrap CSS code as well, so we don't need a CDN link anymore
    • a task copy-js that copies the necessary (Bootstrap) script to the dist/js folder
      • Instead of using CDN links for our scripts, we will copy them from node_modules to the production folder and link to these files in dist/index.html
    • a task browser-sync that launches a browser that stays "in sync":
      • if the Sass code changes, it will be recompiled
      • if there is any change in HTML, CSS or JS code, the browser is reloaded
    • a default task that launches all previous tasks in series

REMARK

More background information (and the detailed code of these Gulp tasks) can be found on the course page Tools > Gulp

  • These Gulp tasks can be launched
    • using the commands gulp <task-name> in a terminal window (in the project folder sass-bs-example)
      • The default task can be started by gulp default or just gulp
    • by double-clicking the corresponding tasks in the Gulp tool window (right-click within the editor window of gulpfile.js and choose Show Gulp Tasks)
      Gulp tool window

TIP

Note that the package.json file also contains the following script:




 




{
    ...
    "scripts": {
        "watch": "gulp"
    },
    ...
}
1
2
3
4
5
6
7

This means that the default Gulp task can also be started by npm run watch!

  • The result after starting the default Gulp task shows the index page, on which some (standard) Bootstrap classes are applied:

index page

# Theming Bootstrap

  • If you study the content of scss/style.scss, you will notice that it consists only of @import statements, one of which (line 19) imports bootstrap.scss (from the folder node_modules)
  • As the other files (_variables.scss, _maps.scss and _reboot.scss) contain no (uncommented) code for now, our compiled file dist/style.css basically is a compiled version of Bootstrap
 
 





 


 






 

/* import Font Awesome and Google font(s) */
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css');
@import url('https://fonts.googleapis.com/css2?family=Abel&family=Abril+Fatface&display=swap');

/* import the necessary Bootstrap files */
@import "../node_modules/bootstrap/scss/functions";
/* Override/add Bootstrap variables here (just before the Bootstraps functions!!) */
@import "variables";
@import "../node_modules/bootstrap/scss/variables";
/* Optional Sass map overrides here (just before the Bootstrap maps!!) */
@import "maps";
@import '../node_modules/bootstrap/scss/maps';
@import "../node_modules/bootstrap/scss/mixins";
@import '../node_modules/bootstrap/scss/utilities';
@import "../node_modules/bootstrap/scss/bootstrap";

/* create custom styles/partials */
@import "reboot";
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# Order of imports is important!

  • On top of the file, we import the external CSS libraries we want to use besides Bootstrap, e.g:
    • Font Awesome for extra icons
    • Google fonts to override the default font that Bootstrap uses
  • Import your local variables file (e.g. variables.scss) AFTER the Bootstrap functions and BEFORE the Bootstrap variables
  • Import your local maps file (e.g. maps.scss) AFTER the Bootstrap variables and BEFORE the Bootstrap maps
  • Import your local styles (e.g. reboot.scss) AT THE END of the file

# Custom variables and Bootstrap variables

  • First, take a closer look at the Bootstrap variables file node_modules/bootstrap/scss/_variables.scss (Tip: Ctrl+click on the file name in PhpStorm)
    Bootstrap variables
  • Every Sass variable in Bootstrap includes the !default flag (see also Sass documentation > Default Values (opens new window)), which allows you to override the variable’s default value in your own Sass files (without modifying Bootstrap’s source code)
  • That's why we import our local variables file JUST BEFORE the Bootstrap ../node_modules/bootstrap/scss/variables

TIP

  • It's not that easy to read the source code to find out which variables are available in Bootstrap!
  • Luckily, the Bootstrap documentation contains a Sass section for every chapter, where you can find more information how to customize the chapter’s variables, maps, components, ...
  • Let's do some quick examples to demonstrate how to override Bootstrap variables and add our own variables that can be used in our custom styles

# Overwrite the default font family

  • In the browser, the font changes:

index page

# Custom styles

  • All your custom styles (styles that are not part of Bootstrap) should be placed in a separate file (e.g. scss/reboot.scss) AT THE END of the scss/style.scss file

# Custom header styles

  • By default, Bootstrap uses only 1 font
  • We want to use an additional font for the headings (h1, h2, h3, h4, h5, h6)
    • with a self-chosen name that is not used in Bootstrap, e.g. $font-family-headers
    • with e.g. the Google font 'Abril Fatface' as value
  • Let's add some custom styles that are only used in some hx elements (h1, h2, h3, h4, h5, h6)
  • In the browser, the font changes:

index page

# Custom maps and Bootstrap maps

# Colors

  • Bootstrap contains 29 color variables (see also Utilities > Colors (opens new window))
    • block 1: 10 color variables
    • block 3: 11 black, white and grayscale variables
    • blok 2 8 variables, based on block 1 and blok 3, ($primary, $secondary, $success, $info, $warning, $danger, $light, $dark) which play a very important role in the framework

index page

  • The $theme-colors map is formed by creating key:value pairs corresponding to these 8 important variables $primary, $secondary, ...

index page

# Overwrite the default theme-colors map and add a new color to the map

  • The default primary color for the $theme-colors map is set to the variable $primary
    • The variable $primary is equal to the variable $blue
    • The variable$blue is equal to the color #0d6efd (Pfff... a lot of variables and colors here)
    • We can to overwrite the $blue variable to change the default primary color
  • The default danger color for the $theme-colors map is set to the variable $danger
    • The variable $danger is equal to the variable $red
    • The $red variable is equal to the color #dc3545
    • Overwrite the $red variable to change the default danger color
  • As such, in the resulting CSS code
    • the colors used in all ...-primary and ...-danger classes are changed
    • a new family of classes ...-itf (.alert-itf, .btn-itf, .text-itf, ...) is added
      itf classes
  • Add the class .text-itf to the header element in index.html and watch the result in the browser:

index page

# Advanced customization

  • Now that you know how to customize Bootstrap, you can start to create your own Bootstrap theme
  • It's impossible to give an overview of all the variables defined in bootstrap/scss/_variables.scss here
  • It's not necessary to adjust/override them all
  • Some interesting possibilities:
    • $enable-variables allow you to quickly modify global styling by enabling/disabling optional features
    • $spacers-map allowing you to modify or add margin/padding classes
    • $body-variables allowing to change the color and background-color of the body element
    • $link-variables for styling anchor elements
    • $table-variables for customizing tables
    • variables related to specific components (forms/input fields, navbar, cards, tooltips, modals, alerts, ...)
    • ...

# Enable/disable optional features

  • In the example:
  • Add the class .py-6 to the header element to add a large vertical padding around it:
    <header class="text-itf my-6">

index page index page

# More custom styles

  • Yet, it is considered to be good practice to check first whether you can realize the desired result by adjusting some properties or adding extra style rules to (an) existing Bootstrap class( es)
  • Example: you want the 'Close' button in the modal to be aligned to the left
    • Inspect the CSS code and observe that the .modal-footer class (containing the 'Close' button) is flex-based with justify-content: flex-end; modal footer

modal footer

# media-breakpoint-up

  • The breakpoints are defined in a map $grid-breakpoints (see: Layout > Breakpoints (opens new window) bs breakpoints

  • Yet, as the values are not stored in separate variables, we cannot refer to them in a @media (min-width: ...) query, and also the use of the keys (e.g. @media (min-width: md)) won't do the job

  • Luckily, the useful mixin media-breakpoint-up() comes to the rescue (see: Layout > Mediaqueries (opens new window) bs media mixin

  • If we want to "darken" the background-color for increasing screen sizes (mobile first!), we include the following code in scss/_reboot.scss

    • The mixin searches for the breakpoint-value (corresponding to md or lg) in the $breakpoints map and copies the content in a correct @media() query, as shown in the corresponding compiled CSS code
Last Updated: 3/13/2023, 11:16:05 AM