Nikhil Dabas

Customizing Bootstrap with a build process

I'm using Bootstrap to power this blog, and I wanted a way to easily customize some of the defaults, but in a way that would allow me to upgrade to future Bootstrap versions easily, while cutting out the parts of the framework that I did not need. This article is about the technique I came up with to achieve that.

Specifically, I had three goals in mind:

Here's a step-by-step guide on how I achieved these goals.

Step 1: Get the Bootstrap source

Bower is probably the easiest way to get the Bootstrap source code into your project, which will also make updating to future releases easy. Create a bower.json file like this:

{
    "name": "nikhildabas.com",
    "version": "1.0.0",
    "dependencies": {
        "bootstrap": "~3.0.0"
    }
}

Then bower install downloads the Bootstrap source into bower_components/bootstrap. I'm going to use the LESS source files from the bower_components/bootstrap/less directory.

Step 2: Include Bootstrap in your own LESS code

Copy the bootstrap.less and responsive.less files from the Bootstrap source into your own css directory. Then create a site.less file like this:

@import "./bootstrap.less";
@import "./responsive.less";

The leading ./ is important because we're going to include the Bootstrap less directory in the LESS include paths; without the ./, LESS will pick up these files directly from the Bootstrap source directory and not our customized versions.

Bootstrap v3.x note: There is no longer a separate responsive.less file, so you need to copy and @import just the bootstrap.less file.

Step 3: Remove the un-needed bits

Now that you have your own local copies of bootstrap.less and responsive.less, you can simply comment out the @import statements that you do not need. My bootstrap.less looks like this:

/*!
 * Bootstrap v2.3.2
 *
 * Copyright 2012 Twitter, Inc
 * Licensed under the Apache License v2.0
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Designed and built with all the love in the world @twitter by @mdo and @fat.
 */

// Core variables and mixins
@import "variables.less"; // Modify this for custom colors, font-sizes, etc
@import "mixins.less";

// CSS Reset
@import "reset.less";

// Grid system and page structure
@import "scaffolding.less";
// @import "grid.less";
// @import "layouts.less";

// Base CSS
@import "type.less";
@import "code.less";
// @import "forms.less";
@import "tables.less";

// Components: common
// @import "sprites.less";
// @import "dropdowns.less";
// @import "wells.less";
// @import "component-animations.less";
// @import "close.less";

// Components: Buttons & Alerts
// @import "buttons.less";
// @import "button-groups.less";
// @import "alerts.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less

// Components: Nav
// @import "navs.less";
// @import "navbar.less";
// @import "breadcrumbs.less";
@import "pagination.less";
// @import "pager.less";

// Components: Popovers
// @import "modals.less";
// @import "tooltip.less";
// @import "popovers.less";

// Components: Misc
// @import "thumbnails.less";
// @import "media.less";
// @import "labels-badges.less";
// @import "progress-bars.less";
// @import "accordion.less";
// @import "carousel.less";
// @import "hero-unit.less";

// Utility classes
@import "utilities.less"; // Has to be last to override when necessary

If you're using Bootstrap v2.x, you need to do the same thing with the responsive version -- comment out un-needed bits from your copy of the responsive.less file.

Is there any Bootstrap left?

You might say that I've cut out too much out of Bootstrap here, and maybe there wasn't any point to using Bootstrap in the first place. True, but I like the fact that I can easily add any of the modules that I might need later.

Step 4: Customize variables

Bootstrap is highly customizable; we just need to set some variables. The complete list of variables that you can customize is in variables.less from the Bootstrap source.

For example, to change the default typography, I've added some lines to my site.less file:

@import "./bootstrap.less";
@import "./responsive.less";

// Bootstrap variables
// -------------------

@sansFontFamily: "Source Sans Pro", Helvetica, Arial, sans-serif;
@monoFontFamily: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace;

@baseFontSize: 15px;
@baseLineHeight: 25px;

@headingsFontWeight: 600;

In Bootstrap v3.x, the variable names have changed a bit:

@import "./bootstrap.less";

@font-family-sans-serif: "Source Sans Pro", Helvetica, Arial, sans-serif;
@font-family-monospace: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace;

@font-size-base: 15px;
@line-height-base: 1.5;

@headings-font-weight: 600;

Note that this must be added after the Bootstrap includes; otherwise, the variables.less from Bootstrap will override our declarations. Interestingly, LESS will use the last declared value of a variable when generating the CSS, even for code that precedes that declaration -- which works to our advantage in this case. Otherwise, we would have had to make a copy of the variables.less flle as well, and edit the variables there.

Step 5: Build

Bootstrap uses Recess to build and minify the CSS, and you can integrate Recess into your build process as well. Get Recess by installing it with npm:

npm install recess

Then, building the CSS is easy:

# Regular build, for debugging
./node_modules/.bin/recess --includePath bower_components/bootstrap/less --compile css/site.less > css/site.css

# Minified build
./node_modules/.bin/recess --includePath bower_components/bootstrap/less --compress css/site.less > css/site.min.css

For a Makefile-based build, you can add these lines to your Makefile:

css: css/site.css css/site.min.css

css/site.min.css: css/site.less css/bootstrap.less css/responsive.less

css/site.css: css/site.less css/bootstrap.less css/responsive.less

%.min.css: %.less
    ./node_modules/.bin/recess --includePath bower_components/bootstrap/less --compress $< > $@

%.css: %.less
    ./node_modules/.bin/recess --includePath bower_components/bootstrap/less --compile $< > $@

Now make css will build the CSS (both regular and minified versions) from your customized LESS files.

Done!

That's it -- include the compiled and minified site.min.css in your templates now.

For me, this process created a 16KB customized build of Bootstrap, which is less than 15% of the unmodified Bootstrap v2.3.2 + responsive minified CSS files. With Bootstrap v3, I have a 12KB build, which is still under 20% of the Bootstrap v3.0.0-rc1 minified distribution.