Applying CSS styles only to certain elements
CssTwitter BootstrapCss Problem Overview
I have an existing website with lots of old pages and forms laid out with tables which I am trying to gradually transition to CSS. I want to use the Twitter Bootstrap stylesheets - particularly the styles for forms - but only on sections of pages where I have explicitly requested them. For example, I might surround the whole form in a div like so:
<div class="bootstrap">
<!-- everything in here should have the Bootstrap CSS applied -->
<form>
<p><label for="text_input">Label</label><input type="text" id="text_input" /></p>
</form>
</div>
I want all other forms to remain the same as they are now, because I won't be able to change them all at the same time. Is there a simple way to do this? I could go through every single style in the Bootstrap CSS and add a parent selector (e.g. 'p' would become 'div.bootstrap p'), but that would take a long time and it would be easy to miss styles.
Edit: If such a thing isn't possible, is there a free tool which can extract all the styles from a file, add a prefix and then save them back again?
Css Solutions
Solution 1 - Css
For Bootstrap 3, it's easier if you use less
:
Download the Bootstrap source code and make a style.less
file like this:
.bootstrap {
@import "/path-to-bootstrap-less.less";
@import "/path-to-bootstrap-responsive-less.less";
}
Finally, you have to compile the less file; there are many alternatives
https://github.com/cloudhead/less.js/wiki/Command-Line-use-of-LESS https://github.com/cloudhead/less.js/wiki/GUI-compilers-that-use-LESS.js
Or use npm
to install less
then compile the style.less
file to style.css
:
npm install -g less
lessc style.less style.css
Solution 2 - Css
The final fix was to use SASS (recommended by someone off-site), as that allows you to nest elements and then automatically produce the final CSS. Step by step the process is:
- Concatenate the two Bootstrap files (
bootstrap.css
andbootstrap-responsive.css
) intobootstrap-all.css
. - Create a new SASS file,
bootstrap-all.scss
, with the contentdiv.bootstrap {
. - Append
bootstrap-all.css
tobootstrap-all.scss
. - Close the
div.bootstrap
selector by appending}
tobootstrap-all.scss
. - Run SASS on
bootstrap-all.scss
to produce a final CSS file. - Run YUI Compressor on the final file to produce a minimised version.
- Add minimised version to head element and wrap everything I want the styles to apply to in
<div class="bootstrap"></div>
.
Solution 3 - Css
I came up with a CSS solution if you can't use LESS/SASS because of work/other reasons.
- I used this site, http://www.css-prefix.com/, and copy/pasted bootstrap.min.css into there. I set prefix ='.bootstrap' and spacer =' '. It will prefix everything with .bootstrap except not perfectly.
- If you do a grep for '.bootstrap @media', you will find that the first class to the right of the opening bracket doesn't have .bootstrap as the parent. Add .bootstrap to all these occurrences, about 68 for me.
- Then replace all '.bootstrap @media' with '@media'.
- Final step is to replace all '.bootstrap @' with '@' (should be about 5 occurrences).
Example:
.bootstrap @media (min-width:768px){.lead{font-size:21px}}
needs to be replaced to
@media (min-width:768px){.bootstrap .lead{font-size:21px}}
Kind of a brute force method, so definitely try the LESS/SASS method above first.
<div>
No Bootstrap
</div>
<div class="bootstrap">
Yes Bootstrap
</div>
Solution 4 - Css
I have an easy solution.
-
Copy bootstrap css content to this (http://css2sass.herokuapp.com/) online css to scss/sass converter.
-
Add your tag information (e.g.
div.bootstrap{
) to the start of scss content and close the tag at the end. -
Copy the whole scss content to this scss to css converter (https://www.sassmeister.com/) and convert it :)
Solution 5 - Css
I wasn't satisfied with any of these answers. Using Less to scope the rules created all sorts of defects. Clearfix, for example was all messed up. And rules like button.close
became button.bootstrap close
instead of what I really wanted: .bootstrap button.close
.
I took a different approach. I'm using PostCSS to process the out-of-the-box CSS that is delivered with Bootstrap. I'm using the Scopify plugin to scope every rule with .bootstrap
.
This mostly gets there. Of course, there are the html
and body
rules that become .bootstrap html
and .bootstrap body
which become non-sensical. No worries... I can just write a PostCSS transform to clean them up:
var elevateGlobalsPlugin = postcss.plugin('elevateGlobals', function(opts) {
return function(css, result) {
css.walkRules(function(rule) {
rule.selector = rule.selector.replace('.bootstrap html', '.bootstrap');
rule.selector = rule.selector.replace('.bootstrap body', '.bootstrap');
});
}
});
Now, I can isolate all Bootstrap styling by adding a class="bootstrap"
at the top level.
Solution 6 - Css
That's tough. You can't https://stackoverflow.com/questions/3298746/apply-different-css-stylesheet-for-different-parts-of-the-same-web-page.
I suspect the only way to do this is to make a separate file for your content to take the bootstrap styles, and i-frame it into the page like this:
<iframe src="/content-to-take-bootstrap-styles.html" ></iframe>
then in content-to-take-bootstrap-styles.html
reference the bootstrap style-sheet in the header. But then you have all the complications of iframes -- e.g.: the iframe element won't grow to accommodate the length of your content.
Solution 7 - Css
You can use ready to use isolated css for Bootstrap 4.1 (compiled with LESS) -
https://github.com/cryptoapi/Isolate-Bootstrap-4.1-CSS-Themes
It have isolated css for themes -
- bootstrapcustom.min.css - default bootstrap 4.1 isolated style
- https://bootswatch.com/cerulean/ darkly.min.css - isolated css
- https://bootswatch.com/darkly/ flatly.min.css - isolated css
- https://bootswatch.com/flatly/ litera.min.css - isolated css
- https://bootswatch.com/litera/ lux.min.css - isolated css
- https://bootswatch.com/lux/ minty.min.css - isolated css
- ...
To use Bootstrap CSS, simply wrap your HTML in a div with the class bootstrapiso, like so:
<div class="bootstrapiso">
<!-- Any HTML here will be styled with Bootstrap CSS -->
</div>
And use any css style from folder css4.1 like so:
<head>
<link rel="stylesheet" href="css4.1/bootstrapcustom.min.css" crossorigin="anonymous">
...
</head>
// https://github.com/cryptoapi/Isolate-Bootstrap-4.1-CSS-Themes
Done!