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:
- Cleanly remove the un-needed bits from Bootstrap. For example, a blog probably does not need progress bars or modals.
- Customize the Bootstrap defaults, like the typography, without writing additional CSS to override bootstrap.css.
- Do all of this without modifying any of the Bootstrap source files. Instead, create a build process to apply the customizations.
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.