I'd like to start learning Twitter Bootstrap and merging it into my site (starting with the form elements) but it breaks the rest of the site if I include it as is.
I'd like to prefix all of the selectors so that I can gradually add content that's bootstrap-styled like so: <div class="bootstrap"><!-- bootstrap styled stuff here --></div>
Because I'm only starting to learn, I don't really know what's possible with less
. I have manually done the selector prefix but I'm curious if there would be a way to do this with less
so that I can learn it by modifying bootstrap while still isolating it in a required bootstrap container.
For now, I have to add prefix in a second step after compiling the less files.
Thanks for any suggestions!
You can edit the file bootstrap.less and encapsulate everything in something like this:
.bootstrap {
// CSS Reset
@import "reset.less";
// Core variables and mixins
@import "variables.less"; // Modify this for custom colors, font-sizes, etc
[...]
}
Update:
Since bootstrap files uses the less & operator, e.g:
// list-group.less (bootstrap 3.0.0)
.list-group-item {
[...]
a& {
[...]
}
}
The compilation of the above code will end up with rules that are semantically wrong and aren't prefixed with .bootstrap:
a.bootstrap .list-group-item {
color: #555555;
}
a.bootstrap .list-group-item .list-group-item-heading {
color: #333333;
}
a.bootstrap .list-group-item:hover,
a.bootstrap .list-group-item:focus {
text-decoration: none;
background-color: #ecf0f1;
}
In order to fix that use the following to compile bootstrap:
$ lessc bootstrap.less | sed -e 's/\(.\+\).bootstrap \(.\+\)/.bootstrap \1\2/g' > output.css
Now the above lines will be compiled to:
.bootstrap a .list-group-item {
color: #555555;
}
.bootstrap a .list-group-item .list-group-item-heading {
color: #333333;
}
.bootstrap a .list-group-item:hover,
.bootstrap a .list-group-item:focus {
text-decoration: none;
background-color: #f5f5f5;
}
To avoid the problems mentioned in periklis's answer: create your own prefixed-bootstrap.less
that re-compiles the compiled bootstrap.css
in :
.bootstrap {
@import (less) 'dist/css/bootstrap.css';
@import (less) 'dist/css/bootstrap-theme.css'; /* optional */
}
No need for sed
commands then. The observations mentioned in Lars Nielsen's answer are of course still valid.
This doesn't really address the issue of naming conflicts. It puts a specific class as a selector before all the bootstrap CSS classes. So to use them you must wrap your HTML inside a container (like a DIV) with a class of that specific name, then the bootstrap CSS will only apply inside that DIV. There are some problems with this.
One issue is that the Bootstrap CSS contains definitions for BODY and HTML which will fail to apply if you put a selector in front of them.
Another issue is when, in your custom CSS, you define some styles a Bootstrap class like ".dropdown" or ".table". You might define aspects of the style that are not defined by Bootstrap, and you might either override Bootstrap styles or mess them up. For example, if Bootstrap defines the padding on ".table" class, and you define the margin on your own ".table" class, then they will combine according the CSS priority rules when the page is rendered. Even if you put a specific custom selector class in front of Bootstrap's ".table" class, and a different selector class in front of your own ".table" class, they will still combine and interact.
Using a selector class like this is not really a "namespace" in the true sense, and does not isolate the CSS fully. The best way to achieve real isolation is to prefix each class name with a unique prefix string.