28

I am building a chrome extension that attaches a widget sort of thing to gmail message. It appears below every email (something like a gmail contextual gadget) when the user is on gmail.com site.

I looked at few css frameworks like twitter bootstrap to use in my app. When I used it in mywidget, it messed with the existing gmail styles because of css class name clash. Is there any other framework that I can use where there would be no name clash? I came across jquery-ui framework. All the classnames here start with .ui-* thereby causing no name clash. Are there any other css frameworks like this with unique class names?

user1566788
  • 585
  • 2
  • 6
  • 14
  • 1
    For bootstrap, using less, have you thought about encapsulating the whole framework in a class, and then use it on the page by wrapping all HTML in this class ? – Sherbrow Aug 05 '12 at 09:58
  • @BillyMoat are you talking about writing all css styles from scratch? I want to use css framework like bootstrap where I can get lots of styles for free and can build my app faster. – user1566788 Aug 07 '12 at 05:02
  • @Sherbrow Does bootstrap framework reset existing styles when I include its css file? Because when the css file got loaded, it changed the font size and style of the entire page (including gmail's font). Does this problem go away when I use it with less? – user1566788 Aug 07 '12 at 05:16
  • 1
    @user1566788 No it does not go away with less, BUT you can decide to add a class `.bootstrap { /* Bootstrap css */ }` so that it applies only within containers having that class. – Sherbrow Aug 07 '12 at 08:06

5 Answers5

50

Update 2: Here is a gist of v3.1.1 provided by @GFoley83

Update: The pastebin joined below is the Twitter Bootstrap version 2.0.4

You should definitively use the up-to-date version and compile it yourself.


Here is what I did with the bootstrap less files :

.tw-bs {
    @import "less/bootstrap.less";
}

And this is the result : http://pastebin.com/vXgRNDSZ

Demo (jsfiddle)

If you don't like tw-bs you can easily do a find/replace, there shouldn't be any conflict.

Sherbrow
  • 17,279
  • 3
  • 64
  • 77
  • Thanks for your suggestion with a demo. – user1566788 Aug 07 '12 at 17:36
  • 1
    After looking at http://jsfiddle.net/Sherbrow/BPhrm/, I have a question. In my case, should I just wrap my whole widget with div like
    ...
    . This should ensure the bootstrap classes get applied only to my widget?
    – user1566788 Aug 07 '12 at 18:05
  • 1
    @user1566788 yes, that's what I would do. You can use a `
    ` or any other element, and only & everything that's inside the `.tw-bs` will be bootstrap.
    – Sherbrow Aug 07 '12 at 19:07
  • Just a note, I'm looking to do the same thing, but currently there is no way to fix conflicts in the Javascript components, right (scripts will still reference the old classes if I'm not missing something)? – nkkollaw Apr 08 '13 at 18:37
  • @nbrogi JS will use the standard classes, but those will follow BS styles only if the elements are positioned inside a `.tw-bs` element. A JS plugin might not work properly if it does not have its CSS classes "behaviors". Try, and if you encounter a problem, post a new question. – Sherbrow Apr 08 '13 at 21:11
  • @Sherbrow definitely: it's not going to work. I was just wondering if somebody had found a solution. – nkkollaw Apr 09 '13 at 09:57
  • That is a nice solution, however it doesn't work for the 'body' CSS tag rule, is there a way in LESS to copy the styles from another rule and apply them to a new one? (A bit like mixins, but without control over all sources) If there was a "@copy" or something, then we could do like `.tw-bs { @import "bootstrap.less"; @copy(body); }` or even better, a @replace that would "remove" the original rule from the compiled file. – Mathieu M-Gosselin Aug 20 '13 at 23:17
  • 2
    @mathieu-m-gosselin keeping the rule isn't really a problem, I had tried using 2 containers and manually adding `html`and `body` rules : it seems to be the next best solution. – Sherbrow Aug 21 '13 at 05:52
  • 2
    @Sherbrow +1, the `html` and `body` issue makes this solution feel dirty, and this solution breaks things if you happen to use this version of BS with a site that has BS (like, if you're distributing a widget and somebody happens to have BS installed, you'll run into problems with modal and other styles being irrecoverably messed up). – orokusaki Nov 18 '13 at 03:12
  • Does this affect the reset styles aswell? – iConnor Dec 10 '13 at 18:55
  • If you do this, how does it affect boostap.js? I namespaced my bootstrap but now my modal doesn't work normal. Is this expected behaviour? – Batman Feb 03 '14 at 19:14
  • 1
    @Batman Yes it is expected. The JS scripts might insert HTML in the page ; whether it's you or the scripts, any markup related to Bootstrap **must** be inside one of your namespaced element (i.e. `
    `. If there are some other unforeseen side-effects, ask about it in another question.
    – Sherbrow Feb 03 '14 at 21:49
  • Thanks for the reply. I ended up just download a custom bootstrap copy and removing the rules which were negatively impacting my page. From there I didn't have to do the Namespacing solution and it seems to work well enough since I just needed the modal functions. – Batman Feb 03 '14 at 21:53
  • @Sherbrow Can you please clarify, have you added `.tw-bs { @import "less/bootstrap.less"; }` on top of every less file under bootstrap\less or what? Because then I don't understand it. – dhblah Feb 04 '14 at 13:05
  • @dhblah what I did, I just renamed bootstrap.less to bootstrap2.less, then added bootstrap.less with content you posted and imported bootstrap2.less, then every thing worked. Is there a cleaner way to do it? – dhblah Feb 04 '14 at 13:29
  • Does Bootstrap 3.1 change anything for this approach? – Acyra Feb 08 '14 at 09:15
  • @Acyra It does not change. And it means that it's still a workaround fix at your own risk (`html` and `body` tags mentioned before) – Sherbrow Feb 09 '14 at 18:37
  • 2
    Here's a gist of Bootstrap 3.1.1 namespaced as above to `.tw-bs` https://gist.github.com/GFoley83/7d71fb9605cad6de2a8b/ – GFoley83 May 31 '14 at 04:10
  • We are using this approach and it breaks when using the & other than at the beginning of a selector. For example: `.tw-bs {.close { button& {}}}` produces `button.tw-bs .close{}`. This exact example happens in [bootstraps close.less](https://github.com/twbs/bootstrap/blob/v3.3.4/less/close.less#L27) – kernel May 05 '15 at 15:33
  • @kernel You might have to compile in two steps, first the bootstrap styles, and then include the generated CSS in another compilation with the `.tw-bs{ /* import generated css */ }` – Sherbrow May 06 '15 at 16:00
  • Thanks @Sherbrow, I found a similar [issue](http://stackoverflow.com/questions/19793508/compiling-issue-in-bootstrap-3-with-namespace) describing your approach. We didn't have time to test it yet. – kernel May 07 '15 at 14:35
6

I used @Sherbrow solution but had to add the responsive file too.

.my-bootstrap-container {
     @import "less/bootstrap.less";
     @import "less/responsive.less";
}

and then run

node_modules/less/bin/lessc demo.less -x > demo.css

If somebody needs the complete step by step tutorial how to compile bootstrap for your own namespaced container I made a blog post about it http://joomla.digital-peak.com/blog/151-how-to-add-bootstrap-to-your-joomla-2-5-extension

The last part is for Joomla but the beginning can be used globally. It has also a link to the latest compiled bootstrap version 2.3.2. Just make a search and replace for .dp-container.

Laoneo
  • 1,546
  • 1
  • 18
  • 25
3

2016 Update: A future way to mitigate this issue (rather than having to recompile bootstrap) is to take advantage of web components, specifically shadow DOM. This allows your app to be self contained (almost like an iFrame) without the web browser having to open a separate page / losing the ability to communicate between pages.

say your component is contained in <div id='plugin'>...</div>

You can move what's inside that div to a tag in your head, eg.

<template id="template"><!--Your Code Here--></template>

Your template can include all the bootstrap link tags and js you want. Then in your javascript/bookmarklet, you can write

var pluginRoot = document.querySelector('plugin').createShadowRoot();
var template = document.querySelector('#template');
var clone = document.importNode(template.content, true);
pluginRoot.appendChild(clone);

You can read a lot more about Web Components (along with Shadow DOM) here: http://webcomponents.org/articles/introduction-to-shadow-dom/

Aaron_H
  • 1,623
  • 1
  • 12
  • 26
  • Nice solution, check browser support before using it: https://caniuse.com/#feat=shadowdomv1 Can be enabled in Firefox, don't work in Edge. – Genjo Mar 23 '18 at 15:23
0

I started off using jquery ui - http://jqueryui.com/ because it has its own css classes which don't clash with gmail. YUI is another such framework that I found. But Sherbrow showed how I can use bootstrap css with our own unique css style names.

user1566788
  • 585
  • 2
  • 6
  • 14
0

The currently accepted answer did not render forms correctly (using SASS and bootstrap 4 beta). The following works for me:

.bootstrap {
    @import 'bootstrap-4.0.0-beta/scss/bootstrap.scss';

    box-sizing: border-box;
}

The box-sizing is important, because, when compiling your SASS stylesheet, the following will be generated.

.bootstrap html {
  box-sizing: border-box;
  ...
}

I.e. the box-sizing property will be placed on an html element inside an element with class="bootstrap" - which of course will not exist. There may be other styles on html and body that you may want to manually add to your styles.

And now you can place content styled using bootstrap inside a bootstrap class:

<div class="bootstrap">
  <div class="container">
    ...
  </div>
</div>
Pete
  • 12,206
  • 8
  • 54
  • 70