115

I want to use Twitter Bootstrap, but only on specific elements, so I need to figure out a way to prefix all Twitter Bootstrap classes with my prefix, or use the less mixins. I'm not experienced with this yet so I don't quite understand how to do this. Here's an example of the HTML that I'm trying to style:

<div class="normal-styles">
  <h1>dont style this with bootstrap</h1>
  <div class="bootstrap-styles">
    <h1>use bootstrap</h1>
  </div>
</div>

In this example, Twitter Bootstrap would normal style both h1s, but I want to be more selective about which areas I apply the Twitter Bootstrap styles.

Andrew
  • 227,796
  • 193
  • 515
  • 708
  • possible duplicate of [css framework for an app with existing stylesheet](http://stackoverflow.com/questions/11813969/css-framework-for-an-app-with-existing-stylesheet) – Sherbrow Dec 20 '12 at 06:31
  • This would help "How to Isolate Bootstrap CSS to Avoid Conflicts "https://formden.com/blog/isolate-bootstrap – Samuel Ev Dec 09 '15 at 12:59

13 Answers13

147

This turned out to be easier than I thought. Both Less and Sass support namespacing (using the same syntax even). When you include bootstrap, you can do so within a selector to namespace it:

.bootstrap-styles {
  @import 'bootstrap';
}

Update: For newer versions of LESS, here's how to do it:

.bootstrap-styles {
  @import (less) url("bootstrap.css");
}

A similar question was answered here.

Community
  • 1
  • 1
Andrew
  • 227,796
  • 193
  • 515
  • 708
  • Hey, I'm trying to follow this but I'm a little confused. I'm working with Angular. Using CDNs I've referenced bootstrap.min.js, less.min.js, and the bootstrap.min.css files. I'm not really sure where to do the namespacing in my application though. – Batman Feb 03 '14 at 18:46
  • After doing this, my modal doesn't work as it use too. Is this to be expected? – Batman Feb 03 '14 at 19:13
  • 2
    @Batman You don't want to use a CDN, because you are essentially rewriting all of Bootstrap to include a prefix. You need to use a preprocessor like SASS to `@import` the original Bootstrap. I had issues with modals as well, I think because Bootstrap applies certain classes to the top level body tag. I don't remember if I found a solution. In the end, I think I ended up writing my own modal replacement. – Andrew Feb 03 '14 at 19:35
  • Yea I'm looking at the js source and yea it adds classes to the boday like class='modal-open' which really screws things up since I can't add my namespace to be body. It would defeat the entire purpose of having a namespace to begin with. Alright, thanks for the reply. I guess I'll play around and try to find a different solution. – Batman Feb 03 '14 at 19:40
  • 4
    This doesn't work anymore after version 3 (http://hereswhatidid.com/2014/02/use-bootstrap-3-styles-within-the-wordpress-admin/) – adamj Aug 12 '14 at 06:15
  • 2
    Can someone please explain where this import statement should go? Looks like a separate .less file. I did that and put it in the bootstrap less folder, but it doesn't compile with namespacing. I think i'm missing something – fehays Aug 20 '15 at 00:17
  • Attention! I don't know why, but less generated in some places css like .my-prefix .my-prefix ..., so you need also to search&replace it. – kolobok Dec 16 '16 at 14:34
  • `.bootstrap-styles * { ... }` with the wildcard worked better for me. @Andrew's answer mostly worked, but bootstrap does some [strange hacks](https://github.com/sass/sass/issues/1873#issuecomment-152293725) that result in clobbered styles. See [my answer here](https://stackoverflow.com/a/70580759/1221537) for more details. – adamdport Jan 04 '22 at 15:02
39

@Andrew great answer. You'll also want to note that bootstrap modifies the body {}, mainly to add font. So when you namespace it via LESS/SASS your output css file looks like this: (in bootstrap 3)

.bootstrap-styles body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 14px;
    line-height: 1.428571429;
    color: #333333;
    background-color: white;
}

but obviously there will not be a body tag inside your div, so your bootstrap content will not have the bootstrap font (since all bootstrap inherits font from parent)

To fix, the answer should be:

.bootstrap-styles {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 14px;
    line-height: 1.428571429;
    color: #333333;
    background-color: white;

    @import 'bootstrap';
}
Kevin
  • 603
  • 5
  • 7
10

Putting @Andrew, @Kevin and @adamj's answers together (plus a few other styles), if you include the following in a file named "bootstrap-namespaced.less", you can simply import 'bootstrap-namespaced.less' into any less file:

// bootstrap-namespaced.less

// This less file is intended to be imported from other less files. 
// Example usage:
// my-custom-namespace {
//  import 'bootstrap-namespaced.less';
// }

// Import bootstrap.css (but treat it as a less file) to avoid problems 
// with the way Bootstrap is using the parent operator (&).
@import (less) 'bootstrap.css';

// Manually include styles using selectors that will not work when namespaced.

@import 'variables.less';

& {
    // From normalize.less

    // Previously inside "html {"
    // font-family: sans-serif; // Overridden below
    -ms-text-size-adjust: 100%;
    -webkit-text-size-adjust: 100%;

    // Previously inside "body {"
    margin: 0;

    // From scaffolding.less

    // Previously inside "html {"
    // font-size: 10px; // Overridden below
    -webkit-tap-highlight-color: rgba(0,0,0,0);

    // Previously inside "body {"
    font-family: @font-family-base;
    font-size: @font-size-base;
    line-height: @line-height-base;
    color: @text-color;
    background-color: @body-bg;
}
Singularity
  • 159
  • 1
  • 8
9

Adding a namespace to bootstrap CSS will break modal functionality as the bootstrap adds a 'modal-backdrop' class directly to the body. A workaround is to move this element after opening the modal, e.g.:

$('#myModal').modal();
var modalHolder = $('<div class="your-namespace"></div>');
$('body').append(modalHolder);
$('.modal-backdrop').first().appendTo(modalHolder); 

You can remove the element in a handler for the 'hide.bs.modal' event.

user3567343
  • 91
  • 1
  • 1
  • If you are using angular with ngbootstrap you can choose to open the modal inside a specific container. `this.modalService.open('myModal', {container: '#modalgoeshere'})` – Ena Nov 28 '18 at 09:02
8

First clone bootstrap from github:

git clone https://github.com/twbs/bootstrap.git

Install requirements:

npm install

Open scss/bootstrap.scss and add your namespace:

.your-namespace {
    @import "functions";
    ...
    @import "utilities/api";
}

Compile bootstrap:

npm run dist

Open dist/css/bootstrap.css and remove the namespace from the html and body tag.

Afterwards copy the content of the dist folder into your project and you're all set.

Have fun!

Tobias Ernst
  • 4,214
  • 1
  • 32
  • 30
  • 2
    It may be worth mentioning now that Bootstrap 5 is on the way and is the main branch now of the repo, that after you clone the repo, you may want to checkout the branch of the version you want to namespace. For instance, I checked out the v4-dev branch so I could namespace v4 of Bootstrap. – Gary Apr 04 '21 at 00:33
3

Use the .less version of the files. Determine which less files you require, then wrap those .less files with:

.bootstrap-styles {

    h1 { }

}

This will give you the output of:

.bootstrap-styles h1 { }
Scott Simpson
  • 3,832
  • 3
  • 27
  • 35
3

I did a GIST with Bootstrap 3 all inside a class named .bootstrap-wrapper https://gist.github.com/onigetoc/20c4c3933cabd8672e3e

I started with this tool: http://www.css-prefix.com/ And fix the rest with search and replace in PHPstorm. All fonts @font-face are hosted on maxcdn.

First line example

.bootstrap-wrapper {font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
Gino
  • 1,834
  • 2
  • 19
  • 20
2

Namespacing breaks the Modal plugin's backdrop div, since that is always added directly to the <body> tag, bypassing your namespacing element which has the styles applied to it.

You can fix this by changing the plugin's reference to $body before it shows the backdrop:

myDialog.modal({
    show: false
});

myDialog.data("bs.modal").$body = $(myNamespacingElement);

myDialog.modal("show");

The $body property decides where the backdrop will be added.

thenickdude
  • 1,640
  • 1
  • 17
  • 18
2

To explain better all the steps what Andrew was talking about for those who don't know what Less is. Here is a link that explain pretty well how it is done step by step How to isolate Bootstrap or other CSS libraries

eKelvin
  • 921
  • 1
  • 9
  • 25
2

Preconditions

Solution

Prefix all css selectors with a class selector:

  1. Copy all the CSS from the CDN into your editor (e.g. http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css)

  2. Wrap the whole thing with a selector (SCSS style), for example .bootstrap-styles:

.bootstrap-styles{
  html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside /* etc... */
}
  1. Use a tool to convert SCSS to CSS. I used https://jsonformatter.org/scss-to-css . (See screenshot at the end)

  2. Self-host the resulting CSS file and include it on the pages where you need it

  3. Wrap the parts that require Bootstrap styling with <div class="bootstrap-styles"> ... </div>

    → Bootstrap styles will only be applied to these parts

  4. You can optionally minimize the resulting CSS.

Caveats

  • Resulting .bootstrap-styles html { selector will obviously not work, as the html tag won't have a parent. You could fix this by changing it into just .bootstrap-styles {. Same applies to body.

  • Icons and fonts with a relative path will be broken. You can find these by searching for url(.

    • Option 1. Remove these styles if you don't need them
    • Option 2. Update the URls to use am absolute path to the CDN (e.g. https://netdna.bootstrapcdn.com/bootstrap/3.1.1/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular
    • Option 3. Download the assets from the CDN and self-host these as well.
  • You can't use a dependency management tool like npm. You'll have to go through these steps everytime you want to update Bootstrap (see precondition).

Screenshot

Converting SCSS to CSS

Converting SCSS to CSS

Luc
  • 544
  • 3
  • 9
1

Most simple solution - start to use custom build isolated css classes for Bootstrap.

For example, for Bootstrap 4.1 download files from css4.1 directory -

https://github.com/cryptoapi/Isolate-Bootstrap-4.1-CSS-Themes

and wrap your HTML in a div with the class bootstrapiso :

<div class="bootstrapiso">
<!-- Any HTML here will be styled with Bootstrap CSS -->
</div>

Page template with isolated bootstrap 4 will be

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="description" content="">
    <title>Page1</title>

    <!-- Isolated Bootstrap4 CSS - -->
    <link rel="stylesheet" href="css4.1/bootstrapcustom.min.css" crossorigin="anonymous">   

    <!-- JS -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" crossorigin="anonymous"></script>
    <script defer src="https://use.fontawesome.com/releases/v5.0.9/js/all.js" crossorigin="anonymous"></script>

  </head>

  <body>

  <div class="bootstrapiso">
  <!-- Any HTML here will be styled with Bootstrap CSS -->
  </div>

  </body>
</html>
1

As a further note for everyone. To get modals working with a backdrop you can simply copy these styles from bootstrap3

.modal-backdrop {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1040;
  background-color: #000;
}
.modal-backdrop.fade {
  filter: alpha(opacity=0);
  opacity: 0;
}
.modal-backdrop.in {
  filter: alpha(opacity=50);
  opacity: .5;
}
Matthew Kirkley
  • 4,138
  • 5
  • 31
  • 33
0

I faced the same issue and method proposed by @Andrew unfortunately didn't help in my specific case. Bootstrap classes collided with classes from another framework. This is how this project has been incepted https://github.com/sneas/bootstrap-sass-namespace. Feel free to use.

sneas
  • 924
  • 6
  • 23