In this tutorial I will show you how to create your own Bootstrap 4 themes using Sass, Gulp and the Bootstrap source code. The result will be a theme that you can apply to new and existing Bootstrap 4 projects to give them a new and fresh look. I've already made some open source themes with this workflow, check out Neon Glow or Vibrant Sea for to see two examples.
In this video I'll show you how the Theme Kit works. You can watch this for a quick view of the essentials. If you're really in a hurry you can even skip the intro and start at 1:34 for the most juicy part. Farther below you'll find step-by-step instructions to get started.
Short version: You need npm and gulp. A text editor and your command line too.
Long version: In order to build our own theme, we will rebuild Bootstrap 4 from the source code, modifying Sass variables
and making use of Bootstrap's mixins and functions. To use the theme kit you'll need at least a text editor and node.js installed on your system.
You can get node from nodejs.org. Once installed, you should be able to run the command
npm from your command line like so:
After that, you can install a node package called Gulp, which you can do by typing
npm install -g gulp-cli. Finally you should be able to run
Note: Your version numbers could be slightly different, but that shouldn't be a problem.
Despite its glamorous name and pompous presentation, the theme kit is a humble package. It's a basic project that includes three main parts:
If you've already got a web project, you would probably want to imitate these techniques with your own build system. The theme kit is simply a minimal project that allows for a quick start and to play around with the theme features without too much effort.
After downloading and extracting the Theme Kit, you'll have to run
npm install inside the directory
to pull all the dependencies. This will download the Bootstrap 4 source code as well as the Sass transpiler for you.
Oof, that's a lot of packages. Welcome to npm :-). The packages are stored under node_modules/, so they won't pollute anything outside the project directory.
Once the dependencies are installed, you can run
gulp to run the build script. You can also run
gulp watch to run the Gulp watcher which will run the build each time you change one of the Sass files.
This is the most practical thing to do when creating a theme.
Now that we have the build script running, let's have a look at our theme's current state in the browser. You can open index.html
in your browser of choice. Optional: What I usually do here is I run a simple development web server right in the project directory using
php -S 0.0.0.0:8080,
so I can then navigate to localhost:8080 instead of opening the file from the file explorer. But this is not strictly necessary.
As you can see, there's a collection of relevant components on the screen, organized into a layout that fits a 1920x1080 display. At this point they're built with the default Bootstrap 4 style, but we're about to change that.
With the gulp watcher running in the background and our testing page loaded in the browser we can now get to theming. Let's have a look at the main Sass file now, which is scss/mytheme.scss:
As you can see, this imports our two other Sass files and the Bootstrap source code which is under node_modules/bootstrap/. Our files custom-variables and custom-styles are empty, which is why our theme is essentially just standard Bootstrap 4 right now.
Okay, let's start off with an easy win: Modifying the existing Bootstrap variables. Open node_modules/bootstrap/
To modify these, we'll make use of the
!default rule. Notice how every last variable in this file has
!default applied to it.
What this means is that the value will only be assigned if it has not yet been defined earlier. So to override these values we
simply define them earlier in the Sass code.
This is the opposite of what you would expect when you think about overriding something in CSS. But it's a very powerful mechanic that allows for modifying the colors without injecting any files into Bootstrap's source. The files under node_modules/ remain completely untouched. This is important enough to repeat: Don't change anything in the node_modules/ directory unless you want to lose your work later.
If you take a look at our file scss/mytheme.scss above, you see that the file scss/_custom-variables.scss is included before Bootstrap. So we can use this file to override any of the default variables that Bootstrap uses. Let's add some variables to scss/_custom-variables.scss and see how our theme starts to take a different form:
If you save this and refresh your browser, you'll see that all the components have gotten a paint job. At this point I should mention that I'm using a browser plugin for Chrome called LivePage which reloads the page automatically for me on changes. My code editor also has a nifty color picker for CSS colors.
Together with Gulp chugging along in the background, I don't even have to leave my code editor anymore. All of this combined, my workflow looks like this (this video is real time and without sound):
You gotta admit that's a pretty neat setup! :-) There are some variables that you can uncomment in _custom-variables.scss but I would encourage you to take a good look at Bootstrap's _variables.scss file to find out what other values you can tinker with.
Some that are worth mentioning are
$enable-shadows. The last two give
Bootstrap back some of it's traditional look when set to true.
If you look at Bootstrap's variable file again, you'll see that there are these map structures:
These are very interesting for us, because they're looped over later in the Bootstrap code to create all sorts of components.
Some examples are
bg-danger and so on. We can amend
these maps painlessly, thanks to the
!default feature and the way these maps were built by the Bootstrap team.
In the code snippet above, the map $theme-colors is defined as a default value, and then merged with the native Bootstrap colors. This is a very
clever implementation because it allows us to extend the map simply by defining our own map in our _custom-variables.scss file:
With three very humble lines of code we're causing a whole set of new components to be generated. We can now use them in our HTML code like this:
The result looks like this:
So far we've only modified the input variables for standard Bootstrap. This provides us with a solid foundation to work from, but there's more power to be leveraged. If we take a look at our main file scss/mytheme.scss again, you'll see there is another file included called custom-styles:
In this file you can put all of your own styles, including those that overwrite some of Bootstrap's styles in the traditional way. This is no different from including your own CSS later in the HTML code and and overwriting stuff as you need. This is likely what you've been doing until today, right?
The reason I'm including it here is this:
Because we included Bootstrap earlier in the same Sass file, we have at our disposal all of the mixins, functions and variables that are included in Bootstrap. These are used by the Bootstrap source code itself to generate components and we can use them to build our own custom components with total control.
Let's get on with an example. Have a look at the folder node_modules/bootstrap/
As you can see there is no magic involved. We can simply call this mixin in our file _custom-styles.scss like this:
And use it in our HTML code like so:
Because we can define all three colors (background, border and text) we have more control over the component. Of course we could add any styles we want right below the @include line to fully customize the alert. This is how this alert looks. Again, 3 lines of Sass code:
Let me pull one last stunt. Let's say we wanted to change the way the default alerts look and give them all a solid
shadow that corresponds to their color. We could of course overwrite them one by one. But remember,
we have Bootstrap's variables available to us in custom-styles and that includes the
Let's look at how alert variants are generated by Bootstrap in the first place:
$theme-colors map is looped over and for each color, the
alert-variant mixin is called. There's
also a function called
theme-color-level which weakens or darkens a color by a numerical value. This is a Bootstrap
function, not a native Sass function, by the way.
So let's use this pattern to amend those alerts in our own code, in scss/_custom-styles.scss:
For each alert we'll add a rule that adds a box shadow with the correct color, softened up a little bit. With everything else on default, they look like this:
If you've modified the theme colors earlier, the shadows will look different of course. Which is exactly why I like using this technique. The shadows respond to the theme colors just like everything else.
Okay, our basic Bootstrap theme is now officially done. Of course there is much more you can do. But these are some basic techniques that give you a good foundation to build upon. You can now take the file css/mytheme.min.css and use it instead of Bootstrap. It essentially still is Bootstrap, so it works exactly the same.
Check out Bootstrap's _variables.scss file, the scss/_mixins folder and the _functions.scss file for more juicy mixins and functions (they're all under node_modules/bootstrap/scss).
There is an official documentation on theming for more info on the topic.