Without any doubt, Twitter's Bootstrap is awesome. So far I am using it in more than 10 projects and I don't regret anything.
Unfortunately, Bootstrap has one major flaw: You can't really add it to your project and manipulate it, without editing the source files. Bootstrap offers a download page where you can chose the parts that you want and where you can enter values for all the variables - but I don't know who on earth works like this. I usually don't know about exact color values for my project until shortly before go-live and I certainly don't want to come back to the download page and download new versions of bootstrap over and over again.
Here is what I want:
My solution might not be the most elegant, but so far it seems to get the job done:
First I add bootstrap as a git submodule to my Django projects:
git submodule add git://github.com/twitter/bootstrap.git myproject/submodules/bootstrap
It is important to add the submodule to a path inside your project root. This way you can place symlinks easily with all relative paths.
Surely you will have a folder that holds your project's CSS files somewhere in your project. For my Django projects that is usually:
Inside of this folder I like to create a
libs folder which holds CSS files
of third party plugins or frameworks that I use. In our case this would be
bootstrap, so let's create a bootstrap folder:
So here is the first part of the trick. Inside of the
bootstrap which we have
just created, we symlink all the
.less files of the Bootstrap framework:
cd myproject/myproject/static/css/libs/bootstrap/ ln -s ../../../../../submodules/bootstrap/less/* .
It would be better to just symlink the whole
less folder instead of all files
lessc is not able to follow such symlinks and would fail
to compile the
Here comes the second part of the trick. We will create copies of the files
1 2 3 4 5
cd myproject/myproject/static/css/ cp libs/bootstrap/bootstrap.less . cp libs/bootstrap/responsive.less . touch my-variables.less touch styles.less
I know, I know, we have just symlinked them, why create another copy now? The
reason is that we won't use the symlinks (you could delete them). Instead
we will make a three simple changes to those two files. First we need to change
the paths to all the imported
sed -i -e 's/import "/import "libs\/bootstrap\//g' bootstrap.less sed -i -e 's/import "/import "libs\/bootstrap\//g' responsive.less
Next we will add an import of our own variables file to both files. The import
should come right after the import of the original
1 2 3 4 5 6 7 8 9 10 11 12 13
# Excerpt from your bootstrap.less copy: ... // CSS Reset @import "libs/bootstrap/reset.less"; // Core variables and mixins @import "libs/bootstrap/variables.less"; @import "my-variables.less"; // Our own variables overrides @import "libs/bootstrap/mixins.less"; ...
Finally we will include our very own
styles.less at the bottom of
bootstrap.less. Styles in this file would override everything else from
1 2 3 4 5 6 7 8
# Excerpt from your bootstrap.less copy: ... // Utility classes @import "libs/bootstrap/utilities.less"; // Has to be last to override when necessary // Our own stuff @import "styles.less";
Repeat the last two steps for
responsive.less as well, of course here you
would add an import to
styles-responsive.less instead of
styles.less at the
That's a whole lot of files to deal with, but the rules are actually quite simple:
When you are done, compile the files
like to save the output as
those two files are the ones that I link in my templates.
First of all, you will have your project specific overrides included in the rest of the Bootstrap framework and don't need to link it in your templates. This saves you one request.
Secondly, we are symlinking to a git submodule, so if a new version or even
just a minor bugfix is released, we can just
cd into the
submodules/bootstrap folder and run
git pull. After that we need to
re-compile our files and that's it - we just updated our Bootstrap files.
There is one thing that can and will still go wrong: The two file that we have
modified and copied (
responsive.less) might differ
when you pull the latest Bootstrap version. Especially when a major new release
happened, there will most definitely be new imports in those files. Luckily
those files are really simple, so you can probably spot the new import at a
glance. A new import would also mean that there is a new file that should be
So in this case, the best workflow would be this:
You could even create a shell script for this task, therefore I consider it a no-brainer :)
We want to use bootstrap as a git submodule because then we can update it
We can't really touch any of the sourcefiles because that would result in merge
conflicts when we pull a new version, but the
variables.less file is full of
gold and really needs to be changed.
As a solution, we just create our own
my-variables.less file and import it
in copies of
responsive.less - those files are just as
likely to change but if they do, we can re-create them in no time.