How to namespace Twitter Bootstrap so styles don't conflict

Twitter BootstrapLess

Twitter Bootstrap Problem Overview


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.

Twitter Bootstrap Solutions


Solution 1 - Twitter Bootstrap

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.

Solution 2 - Twitter Bootstrap

@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';
}

Solution 3 - Twitter Bootstrap

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;
}

Solution 4 - Twitter Bootstrap

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.

Solution 5 - Twitter Bootstrap

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!

Solution 6 - Twitter Bootstrap

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 { }

Solution 7 - Twitter Bootstrap

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%}

Solution 8 - Twitter Bootstrap

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.

Solution 9 - Twitter Bootstrap

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

Solution 10 - Twitter Bootstrap

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>

Solution 11 - Twitter Bootstrap

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;
}

Solution 12 - Twitter Bootstrap

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.

Solution 13 - Twitter Bootstrap

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndrewView Question on Stackoverflow
Solution 1 - Twitter BootstrapAndrewView Answer on Stackoverflow
Solution 2 - Twitter BootstrapKevinView Answer on Stackoverflow
Solution 3 - Twitter BootstrapSingularityView Answer on Stackoverflow
Solution 4 - Twitter Bootstrapuser3567343View Answer on Stackoverflow
Solution 5 - Twitter BootstrapTobias ErnstView Answer on Stackoverflow
Solution 6 - Twitter BootstrapScott SimpsonView Answer on Stackoverflow
Solution 7 - Twitter BootstrapGinoView Answer on Stackoverflow
Solution 8 - Twitter BootstrapthenickdudeView Answer on Stackoverflow
Solution 9 - Twitter BootstrapeKelvinView Answer on Stackoverflow
Solution 10 - Twitter Bootstrapuser3879851View Answer on Stackoverflow
Solution 11 - Twitter BootstrapMatthew KirkleyView Answer on Stackoverflow
Solution 12 - Twitter BootstrapsneasView Answer on Stackoverflow
Solution 13 - Twitter BootstrapLucView Answer on Stackoverflow