Comment créer un espace de noms Twitter Bootstrap pour que les styles ne soient pas en conflit

106

Je veux utiliser Twitter Bootstrap, mais uniquement sur des éléments spécifiques, je dois donc trouver un moyen de préfixer toutes les classes Twitter Bootstrap avec mon préfixe, ou utiliser le moins de mixins. Je n'ai pas encore d'expérience avec cela, donc je ne comprends pas très bien comment faire cela. Voici un exemple du HTML que j'essaie de styliser:

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

Dans cet exemple, Twitter Bootstrap h1appliquerait un style normal aux deux , mais je veux être plus sélectif sur les zones dans lesquelles j'applique les styles Twitter Bootstrap.

Andrew
la source
Cela aiderait "Comment isoler le CSS Bootstrap pour éviter les conflits" formden.com/blog/isolate-bootstrap
Samuel Ev

Réponses:

132

Cela s'est avéré plus facile que je ne le pensais. Less et Sass prennent en charge les espaces de noms (même en utilisant la même syntaxe). Lorsque vous incluez bootstrap, vous pouvez le faire dans un sélecteur pour l'espace de noms:

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

Mise à jour: pour les versions plus récentes de LESS, voici comment procéder:

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

Une question similaire a été répondue ici.

Andrew
la source
Hé, j'essaye de suivre ça mais je suis un peu confus. Je travaille avec Angular. En utilisant des CDN, j'ai référencé bootstrap.min.js, less.min.js et les fichiers bootstrap.min.css. Je ne sais pas vraiment où faire l'espacement de noms dans mon application.
Batman
Après cela, mon modal ne fonctionne pas comme il l'utilise aussi. Doit on s'y attendre?
Batman
2
@Batman Vous ne voulez pas utiliser de CDN, car vous réécrivez essentiellement tout Bootstrap pour inclure un préfixe. Vous devez utiliser un préprocesseur comme SASS pour @importle Bootstrap d'origine. J'ai également eu des problèmes avec les modaux, je pense que parce que Bootstrap applique certaines classes à la balise body de niveau supérieur. Je ne me souviens pas si j'ai trouvé une solution. En fin de compte, je pense que j'ai fini par écrire mon propre remplacement modal.
Andrew le
4
Cela ne fonctionne plus après la version 3 ( hereswhatidid.com/2014/02/… )
adamj
2
Quelqu'un peut-il expliquer où doit aller cette déclaration d'importation? Ressemble à un fichier .less séparé. Je l'ai fait et je l'ai mis dans le dossier bootstrap less, mais il ne se compile pas avec un espace de noms. Je pense qu'il me manque quelque chose
fehays
35

@Andrew excellente réponse. Vous voudrez également noter que bootstrap modifie le corps {}, principalement pour ajouter une police. Ainsi, lorsque vous l'espace de nom via LESS / SASS, votre fichier css de sortie ressemble à ceci: (dans 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;
}

mais évidemment il n'y aura pas de balise body à l'intérieur de votre div, donc votre contenu bootstrap n'aura pas la police bootstrap (puisque tout bootstrap hérite de la police du parent)

Pour corriger, la réponse devrait être:

.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
la source
Vous avez oubliémargin: 0;
kolobok
1
Attention! Je ne sais pas pourquoi, mais moins généré dans certains endroits css comme .my-prefix .my-prefix ..., vous devez donc également le rechercher et le remplacer.
kolobok
10

En rassemblant les réponses de @Andrew, @Kevin et @ adamj (plus quelques autres styles), si vous incluez les éléments suivants dans un fichier nommé "bootstrap-namespaced.less", vous pouvez simplement importer 'bootstrap-namespaced.less' dans n'importe quel fichier. fichier:

// 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;
}
Singularité
la source
1
Merci. C'est vraiment la meilleure solution.
kolobok
Fonctionne parfaitement !
Kévin Berthommier le
8

L'ajout d'un espace de noms pour bootstrap CSS interrompra la fonctionnalité modale car le bootstrap ajoute une classe 'modal-backdrop' directement au corps. Une solution de contournement consiste à déplacer cet élément après l'ouverture du modal, par exemple:

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

Vous pouvez supprimer l'élément dans un gestionnaire pour l'événement 'hide.bs.modal'.

user3567343
la source
Si vous utilisez angular avec ngbootstrap, vous pouvez choisir d'ouvrir le modal à l'intérieur d'un conteneur spécifique. this.modalService.open('myModal', {container: '#modalgoeshere'})
Ena
3

Utilisez la version .less des fichiers. Déterminez les fichiers dont vous avez besoin en moins, puis enveloppez ces fichiers .less avec:

.bootstrap-styles {

    h1 { }

}

Cela vous donnera la sortie de:

.bootstrap-styles h1 { }
Scott Simpson
la source
3

J'ai fait un GIST avec Bootstrap 3 dans une classe nommée .bootstrap-wrapper https://gist.github.com/onigetoc/20c4c3933cabd8672e3e

J'ai commencé avec cet outil: http://www.css-prefix.com/ Et corrige le reste avec la recherche et le remplacement dans PHPstorm. Toutes les polices @ font-face sont hébergées sur maxcdn.

Exemple de première ligne

.bootstrap-wrapper {font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
Gino
la source
2

L'espacement de noms rompt le div d'arrière-plan du plugin Modal, car il est toujours ajouté directement à la balise <body>, en contournant votre élément d'espacement de noms auquel les styles sont appliqués.

Vous pouvez résoudre ce problème en modifiant la référence du plugin $bodyavant d'afficher le fond:

myDialog.modal({
    show: false
});

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

myDialog.modal("show");

La $bodypropriété décide où la toile de fond sera ajoutée.

alorsickdude
la source
1

Solution la plus simple: commencez à utiliser des classes CSS isolées de construction personnalisée pour Bootstrap.

Par exemple, pour Bootstrap 4.1, téléchargez des fichiers à partir du répertoire css4.1 -

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

et enveloppez votre HTML dans un div avec la classe bootstrapiso:

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

Le modèle de page avec bootstrap isolé 4 sera

<!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>
user3879851
la source
0

J'ai rencontré le même problème et la même méthode que celle proposée par @Andrew n'a malheureusement pas aidé dans mon cas spécifique. Les classes Bootstrap sont entrées en collision avec des classes d'un autre framework. C'est ainsi que ce projet a été lancé https://github.com/sneas/bootstrap-sass-namespace . N'hésitez pas à l'utiliser.

sneas
la source
0

Comme une note supplémentaire pour tout le monde. Pour que les modaux fonctionnent avec une toile de fond, vous pouvez simplement copier ces styles depuis 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
la source
0

Premier clonage de bootstrap depuis github:

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

Exigences d'installation:

npm install

Ouvrez scss / bootstrap.scss et ajoutez votre espace de noms:

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

Compilez le bootstrap:

npm run dist

Ouvrez dist/css/bootstrap.csset supprimez l'espace de noms de la balise htmlet body.

Ensuite, copiez le contenu du dossier dist dans votre projet et vous êtes prêt.

S'amuser!

Tobias Ernst
la source