Skip to main content

Creating a bootstrap theme - a guide

Creating a bootstrap theme

By now Twitter's Bootstrap has become commonplace, I see it all the time - for better or for worse, chances are its something you're going to run into in the Front End world.

Bootstrap can make for a quick, easy, and strong foundation for the style and basic structure of your website - if done right. If done wrong however it can be an absolute pain in the arse.

I've definitely seen it done both ways, so here are a few tips to hopefully steer you in the right direction.

Setup

First thing to note is that while there is a sass version available, Bootstrap 3 is written using less, so that's what I'll be using in my examples. It's essential to use one of these preprocessors for what we are trying to achieve here.

Download bootstrap

So obviously we need to download bootstrap, use npm, or bower or whatever you prefer - I'll use npm:

npm install bootstrap

That's gonna download bootstrap for you, including all the source less files - which are what we are interested in.

It might be a bit obvious but the first thing to note is that you should never edit these files, not the components, not the variables, not anything.

Import Bootstrap

Next we want to import the bootstrap less files into our theme - I like to have a single less file to import all of bootstrap. I'm gonna use this folder structure for this example:

my-project/
├── node_modules/bootstrap/
└── src/
    └── less/
        ├── bootstrap-theme/
        │   ├── bootstrap.less
        │   └── bootstrap-theme.less
        └── my-project.less

So inside my bootstrap-theme/bootstrap.less file I add all the bootstrap imports from node_modules/bootstrap/bootstrap.less with the paths updated - you can create a variable for this if you like.

// Core variables and mixins
@import ~"@{path-bootstrap}/variables.less";
@import ~"@{path-bootstrap}/mixins.less";

// Reset and dependencies
@import ~"@{path-bootstrap}/normalize.less";
@import ~"@{path-bootstrap}/print.less";
@import ~"@{path-bootstrap}/glyphicons.less";

// Core CSS
@import ~"@{path-bootstrap}/scaffolding.less";
@import ~"@{path-bootstrap}/type.less";
@import ~"@{path-bootstrap}/code.less";
@import ~"@{path-bootstrap}/grid.less";
@import ~"@{path-bootstrap}/tables.less";
@import ~"@{path-bootstrap}/forms.less";
@import ~"@{path-bootstrap}/buttons.less";

...

All bootstrap-theme.less does at the moment is import the bootstrap.less file - which is just for the sake of keeping things tidy - we'll be adding more to it soon.

The idea here is pretty simple - we now we have our project, which will import bootstrap-theme which will itself import bootstrap.

Overriding Bootstrap

As I said, we aren't going to be editing bootstrap itself, we're going to use overrides to make any changes we need. Often bootstrap has made the property you want to change available as a variable, sometimes not - it's really important to actually look at bootstrap's less files to see what you are working with. Look, but don't touch.

Variables

Bootstrap does a pretty decent job of making variables for the things you are most likely to want to change.

We are already importing all bootstrap's variables by default, but instead of editing those we can add a less file for any variable overrides we want to make.

bootstrap-theme/
├── bootstrap.less
├── bootstrap-theme.less
└── variables.less

Now our bootstrap-theme.less file can import this file after bootstrap so that any overrides will be applied.

// Bootstrap
@import "bootstrap.less";

// Variables
@import "variables.less";

You can check node_modules/bootstrap/variables.less for the full list of variables that are available.

Keep in mind that some variables are used across multiple components (for example @padding-base-vertical and @padding-base-horizontal) so it's worth checking where they are used before you change them. Others are clearly namespaced so you can tell they will only affect specific components (eg @tooltip-color) and you can safely override them.

Style overrides

Unfortunately not everything can be put into a variable, some designs of components are just fundamentally different - you're going to need to override the base styles of components too. So lets take a simple example - panels.

Let's say your designs require your panels to have an inset box shadow - panels have a box shadow by default, but not an inset one, and there is no variable for this. So when we need to make a style change like this we create a file in our theme that matches the one in bootstrap for this component.

bootstrap-theme/
├── bootstrap.less
├── bootstrap-theme.less
├── panels.less
└── variables.less

We then import the file in our bootstrap-theme.less file.

// Bootstrap
@import "bootstrap.less";

// Variables
@import "variables.less";

// Component overrides
@import "panels.less"

And then any style you want to change for panels can be added in the new panels.less file - they are imported after the bootstrap styles so they will take precedence.

.panel {
  .box-shadow(inset 1px 1px 1px rgba(0,0,0,.05));
}

If you want to be really fancy you can even make your own variables for things like this so that any projects that use your theme have the ability to override them! How crazy you want to go with that is up to you but its a good idea to keep in mind the idea of making things easy to override.

Even if you are only going to use the theme in one project it is good practice to think like this - it helps to keep project specific code in the project where it belongs and not in the bootstrap theme.

Whenever you override a component in this way you should always take the time to look through the default less file for it in bootstrap - it will give you a good idea of how the component works and any variants that exist that you might not be aware of and could potentially break.

Mixins

Many bootstrap components have variants for size, colour, etc - bootstrap generally uses its own mixins to create these variants. Be sure to make use of bootstrap's mixins whenever possible and note that they too can be overridden.

Bootstrap keeps its mixins in a folder and any mixins relating to a component are contained in a file with a name matching the component less file. For example, the mixins for bootstrap/panels.less are contained in bootstrap/mixins/panels.less. I'd recommend also following this naming convention if you plan on overriding any mixins

Also if you do override a mixin keep in mind that it will be run after the original mixin - not instead of it - any undesired styles that are generated in the original mixin will need to be specifically overridden.

Running the bootstrap docs

You're probably familiar with the bootstrap docs but did you know you can run them yourself? This is a great way to see how your styles affect all of the components and display a list of what's available to your team.

I honestly can't recommend this enough, the setup is relatively easy and its a pretty definitive way to see the state of your theme.

Bootstrap have a guide to running their docs on their Github page that you can use.

Summary

The idea is pretty simple but I often see it poorly executed. Bootstrap is a tool to make the front end easier and get you up and running with something that looks decent right away but it can be a really solid foundation for your website if done right.

The problem is I think that it often gets thrown in a project at the beginning in a rush to get something together, often by someone who isn't that interested in the Front End and it can end up becoming a burden.

If you get in right at the start and do things the right way you will be thankful for it later down the line.

In summary I'd say you should keep these things in mind:

  • Never edit bootstrap itself
  • Use bootstraps variables where you can - but be aware of what they affect
  • Create style overrides that sit on top of bootstrap
  • Make use of bootstrap's mixins
  • Run bootstraps docs to keep track of how your changes affect everything

Good luck!