June 7th 2020
Startup enthusiast. React and Ruby on Rails lover
Twitter Bootstrap is the most popular CSS framework. It has been so since its first release in 2011. Its constantly rising popularity begs the question: what aspect of it allows room for the different look and feel of millions of websites that are built on top of it? In this article, I demonstrate how to modify Bootstrap 4 according to a design that has its own color theme, responsive breakpoints and spacing styles.
I am new to front-end development. And I came across Bootstrap a few years ago. After doing some initial reading about its content and documentation, I kept wondering how its customization works. Last few weeks saw me working on a couple of Bootstrap and Sass projects, and one of them involved using SCSS to customize Bootstrap 4 based on the design I received.
I’m presenting my learning in this write-up.
First things first: if you Googled for this article using “customize Bootstrap 4” or similar keywords, I take it for granted that you have a strong foundation in HTML5 and CSS3, and you have completed at least one project that significantly covered the Bootstrap 4 documentation. Also, some basic understanding of Sass is essential, especially about variables, mixins, value types (maps, functions) and loops.
Secondly, modification of Bootstrap requires either downloading or installing the framework to your project folder. In my case, I have npm available globally and I used it to install Bootstrap 4 into my workspace.
npm install bootstrap
Upon installing Bootstrap 4, I have a folder structure that looks like this:
project-folder/ ├── node_modules/ └── bootstrap/ ├── js └── scss
Next, inside my project directory, I create a folder to hold my custom Sass/CSS files. This custom folder should be outside the node_modules directory — as it is advised to keep the custom files isolated from Bootstrap’s core files.
project-folder/ ├── node_modules/ │ └── bootstrap/ │ ├── js │ └── scss └── bs-custom/ ├── overrides.scss └── main.scss
The _variables.scss File
Bootstrap 4’s core files include a file named _variables.scss. This is the file that contains all the variables that we will modify in order to customize Bootstrap.
The overrides.scss File
Moving on from there, I create an overrides.scss (or one with any other descriptive name) file inside the custom folder. This file will be the base where I override the default Bootstrap variables originally contained in the _variables.scss file. We’ll come to that in a minute. But before that, I should start navigating into the Bootstrap core folder to import the Sass files necessary for my project.
To begin with, you can import the whole of Bootstrap for the sake of learning. However, once you have got enough practice, it is recommended that you import only the ones that you need for your project — because it helps reduce the size of the resulting CSS file that is shipped to the client side.
// overrides.scss // Option 1: Import all Bootstrap files @import "../node_modules/bootstrap/scss/bootstrap";
Granted I use only the parts of Bootstrap that I need, imports are divided into two chunks: Required and Optional. Notice that the _variables.scss file is among the mandatory files.
// overrides.scss // Option 2: Import only the files you need // Mandatory @import "../node_modules/bootstrap/scss/functions"; @import "../node_modules/bootstrap/scss/variables"; @import "../node_modules/bootstrap/scss/mixins"; // Optional @import "../node_modules/bootstrap/scss/reboot"; @import "../node_modules/bootstrap/scss/type"; @import "../node_modules/bootstrap/scss/images"; @import "../node_modules/bootstrap/scss/code"; @import "../node_modules/bootstrap/scss/grid"; . . .
The main.scss File
Then, I create a main.scss file inside the custom folder. This file is where I will import the overrides.scss file and style any necessary non-Bootstrap classes. This is the file that will ultimately precompile and generate the stylesheet that I will link to my HTML page.
// main.scss // Import overrides.scss @import "./overrides.scss";
If you survey the _variables.scss file in your code editor, you will notice that all the variables contain a CSS !default flag. This is self-explanatory, and suggests that they can all be overridden. This is what gives Bootstrap the power to make space for creating unique websites.
Notice that _variables.scss has 1100+ lines, indicating the number of variables available for modification. I suggest you scan through the file and see what variables are out there. The variable names are quite descriptive, so they should give you some insight into what they represent.
Overriding the Defaults
Now that I have everything set up and well-figured-out, it’s time to get my hands dirty and start modifying some variables in the overrides.scss file.
It is worth mentioning at this point that, since overridden variables will be used globally, they need to be declared at the top of the overrides.scss file — above the @import declarations.
Colors are the most noticeable aspect of a design. So, I’ll start with modifying the color variables.
For my project, I have a scheme composed of three colors. So, I create three variables and assign them their respective colors.
//overrides.scss $grocery-pink: #d65649; $grocery-gray: #444; $grocery-black: #000;
Next, I need to adjust the $theme-colors map accordingly. I do that by overriding the $primary and $secondary variables in the overrides.scss file.
$primary: $grocery-pink; $secondary: $grocery-gray; $tertiary: $grocery-black;
Modifying these variables automatically updates the $theme-colors map to adopt the newly assigned colors.
$theme-colors: () !default; $theme-colors: map-merge( ( "primary": $primary, "secondary": $secondary, "success": $success, "info": $info, "warning": $warning, "danger": $danger, "light": $light, "dark": $dark ), $theme-colors );
Then, I need to insert my tertiary color as an additional item in the $theme-colors map. Like so:
$theme-colors: ( "tertiary": $tertiary );
Notice how easy it is to add a new item. You just place the key-value pair inside the map and it is concatenated to the end.
Since I changed the $primary and $secondary values, their respective defaults ($blue and $gray-600) are lost. If I need them back, I can just append them at the end of the $theme-colors map using the addition method shown above.
So, what have I affected with these few changes? It turns out, quite a number of things.
By changing the $primary variable, I have changed the default text color of my links and pagination, the focus box shadow of my form inputs, the default background color of buttons in forms, jumbotron, cards, modals and more.
Modifying the $primary and $secondary variables also changed the primary and secondary variants of color utilities for text, backgrounds, alerts, buttons, badges, tabs, pills and so on.
There is a set of more color variables that can be used to style non-Bootstrap classes. These variables also incorporate a $colors map. This map is used to define a Sass function that loops through the map and generates individual values from it. Then these color values as well can be used to style non-Bootstrap classes.
$blue: #007bff !default; $indigo: #6610f2 !default; $purple: #6f42c1 !default; $pink: #e83e8c !default; $red: #dc3545 !default; $orange: #fd7e14 !default; $yellow: #ffc107 !default; $green: #28a745 !default; $teal: #20c997 !default; $cyan: #17a2b8 !default;
Obviously, you can also replace the values of these variables with your own version of the colors — as well as add new colors to this list. You’ll need to remove the !default flag there.
Modifying Responsive Breakpoints
Bootstrap has five screen sizes.
$grid-breakpoints: ( xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px ) !default;
For my project, I only need three screen sizes:
- mobile: up to 768pxt
- ablet: up to 1024px
- desktop: from 1024px
So, I need to remove two items from the $grid-breakpoints map: “xs” and “xl”.
However, removing an item from a map is a bit tricky in Bootstrap. We have to use the map-remove() function in Sass, and we have to place the code in between the Mandatory and Optional @import declarations in the overrides.scss file.
// Mandatory @import "../node_modules/bootstrap/scss/functions"; @import "../node_modules/bootstrap/scss/variables"; @import "../node_modules/bootstrap/scss/mixins"; $grid-breakpoints: map-remove($grid-breakpoints, xs, xl); // Optional @import "../node_modules/bootstrap/scss/reboot"; @import "../node_modules/bootstrap/scss/type"; . . .
I also change the value of the “sm” key to 0 and that of the “lg” key to 1024px:
$grid-breakpoints: ( sm: 0, lg: 1024px );
But it turns out that this change does not produce the “-md-” classes that I need.
The reason is not clear to me (if you know, please leave a comment), but it may be due to the _assert-ascending mixin that ensures the $grid-breakpoints map items are in an ascending order. The order of the above code probably disrupts that of the map and hence “-md-” classes are not created.
@include _assert-ascending($grid-breakpoints, “$grid-breakpoints”);
When I add the “md” breakpoint with its already defined value in-between “sm” and “lg”, “-md-” classes appear in the main.css file.
$grid-breakpoints: ( sm: 0, md: 768px, lg: 1024px );
So what are the results of these changes?
Clearly, my large screen breakpoint has now moved to 1024px, from 992px.
Besides, if I search in main.css file, the removal of the “xl” item wiped off all the responsive utility classes for this particular breakpoint. For example, all the “col-xl-” classes are gone. Similarly, “-xl-” classes for flex and text-alignment utilities also disappeared.
This helps reduce the size of the compiled CSS file.
It is possible to set the maximum width of a container for a particular screen size.
Bootstrap’s defaults are:
$container-max-widths: ( sm: 540px, md: 720px, lg: 960px, xl: 1140px ) !default;
I’ll remove the “sm” and “xl” items and change this map to:
$container-max-widths: ( md: 750px, lg: 1010px );
Once again, here’s how to remove items from a map:
// Mandatory @import "../node_modules/bootstrap/scss/functions"; @import "../node_modules/bootstrap/scss/variables"; @import "../node_modules/bootstrap/scss/mixins"; $grid-breakpoints: map-remove($grid-breakpoints, xs, xl); $container-max-widths: map-remove($container-max-widths, sm, xl); // Optional @import "../node_modules/bootstrap/scss/reboot"; @import "../node_modules/bootstrap/scss/type";
Margin and Padding
Bootstrap’s spacing classes (those starting with “m” and “p”) are styled based on the $spacers map:
$spacers: map-merge( ( 0: 0, 1: ($spacer * .25), 2: ($spacer * .5), 3: $spacer, 4: ($spacer * 1.5), 5: ($spacer * 3) ), $spacers );
I’ll change the value of 4 and add a sixth item:
$spacers: ( 4: ($spacer * 2), // New item 6: ($spacer * 4) );
This changes the values of 4th level margin and padding (mt-4, mb-4, px-4, py-4, etc.) utilities from 1.5rem to 2rem. This also adds a new generation of padding and margin classes that end with “-6”.
I’ll slightly change the column gutters. 15px a side looks too wide for me. I’ll bring it down to 10px by setting the $grid-gutter-width to 20px.
Vertical Margin of <hr>
Finally, I’ll set the vertical margin of hr tags to 0.625rem:
$hr-margin-y: $spacer * 0.625;
The Way Forward
I hope the above examples have shed some light on to how Bootstrap 4 variables are customized to match a specific design.
A lot more can be changed. You can modify typographic properties like font families, font sizes, font-weight, and so on. You can tweak border colors, radius, box shadows, etc. You can change the look and feel of tables, forms, buttons, modals, and all other components.
But to make them happen, you will need to thoroughly examine the _variables.scss file and figure out what can be modified. You will need to understand how functions and loops are used to generate CSS classes from various maps defined in the file. Some variables are dependent on other variables, so you’ll need to understand those dependencies in order to able to manipulate them effectively.
Below, I list some articles that helped me understand the concepts when I was researching the topic. I assume they will also guide you in getting a clear idea about how Bootstrap customization works.
Bootstrap 4 Customization Checklist
Bootstrap’s power lies in its ability to be tailored according to the individual designs that site builders implement. Almost anything can be personalized by overriding the variables in the _variables.scss file. Changing these variables can dramatically alter the look and feel of a website.
In this article, we saw how colors, responsive breakpoints and some spacing utilities can be modified in order to achieve a site’s design goals. The examples shown were intended to provide some initial guidance so that you can then opt for customizing the framework more comprehensively.
If you found this article helpful, please feel free to give it a like/clap/thumbs up. That would mean a lot to me. Comments and suggestions are welcome. I am new to writing, so your feedback will help me a lot.