Como usar o namespace do Twitter Bootstrap para que os estilos não entrem em conflito

106

Quero usar o Twitter Bootstrap, mas apenas em elementos específicos, então preciso descobrir uma maneira de prefixar todas as classes do Twitter Bootstrap com meu prefixo ou usar menos mixins. Não tenho experiência com isso ainda, então não entendo muito bem como fazer isso. Aqui está um exemplo do HTML que estou tentando estilizar:

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

Neste exemplo, o Twitter Bootstrap normalizaria ambos os estilos h1, mas quero ser mais seletivo sobre as áreas em que aplico os estilos do Twitter Bootstrap.

Andrew
fonte
Isso ajudaria "Como isolar CSS de bootstrap
Samuel Ev

Respostas:

131

Isso acabou sendo mais fácil do que eu pensava. Tanto Less quanto Sass suportam namespacing (usando a mesma sintaxe até). Ao incluir bootstrap, você pode fazer isso em um seletor para atribuir um nome a ele:

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

Atualização: para versões mais recentes do LESS, veja como fazer:

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

Uma pergunta semelhante foi respondida aqui.

Andrew
fonte
Ei, estou tentando seguir isso, mas estou um pouco confuso. Estou trabalhando com o Angular. Usando CDNs Eu mencionei bootstrap.min.js, less.min.js e os arquivos bootstrap.min.css. Não tenho certeza de onde fazer o namespacing em meu aplicativo.
Batman
Depois de fazer isso, meu modal não funciona como ele usa também. Isso era esperado?
Batman
2
@Batman Você não quer usar um CDN, porque está essencialmente reescrevendo todo o Bootstrap para incluir um prefixo. Você precisa usar um pré-processador como o SASS para @importo Bootstrap original. Tive problemas com modais também, acho que porque o Bootstrap aplica certas classes à tag de corpo de nível superior. Não me lembro se encontrei uma solução. No final, acho que acabei escrevendo minha própria substituição modal.
Andrew
4
Isso não funciona mais após a versão 3 ( hereswhatidid.com/2014/02/… )
adamj
2
Alguém pode explicar onde esta declaração de importação deve ir? Parece um arquivo .less separado. Fiz isso e coloquei na pasta bootstrap less, mas não compila com namespacing. Acho que estou perdendo algo
fehays de
35

@Andrew ótima resposta. Você também deve notar que o bootstrap modifica o corpo {}, principalmente para adicionar fonte. Então, quando você atribui um namespace via LESS / SASS, seu arquivo css de saída fica assim: (no 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;
}

mas obviamente não haverá uma tag body dentro de sua div, então seu conteúdo bootstrap não terá a fonte bootstrap (já que todo bootstrap herda a fonte do pai)

Para corrigir, a resposta deve ser:

.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
fonte
Você esqueceumargin: 0;
Kolobok
1
Atenção! Não sei por que, mas menos gerado em alguns lugares css como .my-prefix .my-prefix ..., então você precisa também pesquisar e substituí-lo.
Kolobok
10

Colocando as respostas de @Andrew, @Kevin e @adamj juntas (mais alguns outros estilos), se você incluir o seguinte em um arquivo chamado "bootstrap-namespaced.less", você pode simplesmente importar 'bootstrap-namespaced.less' para qualquer menos Arquivo:

// 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;
}
Singularidade
fonte
1
Obrigado. É realmente a melhor solução.
Kolobok
Funciona perfeitamente !
Kévin Berthommier
8

Adicionar um namespace ao CSS de bootstrap interromperá a funcionalidade modal, pois o bootstrap adiciona uma classe de 'pano de fundo modal' diretamente ao corpo. Uma solução alternativa é mover este elemento após abrir o modal, por exemplo:

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

Você pode remover o elemento em um manipulador para o evento 'hide.bs.modal'.

user3567343
fonte
Se estiver usando angular com ngbootstrap, você pode escolher abrir o modal dentro de um contêiner específico. this.modalService.open('myModal', {container: '#modalgoeshere'})
Ena
3

Use a versão .less dos arquivos. Determine quais menos arquivos você precisa e agrupe esses arquivos .less com:

.bootstrap-styles {

    h1 { }

}

Isso lhe dará a saída de:

.bootstrap-styles h1 { }
Scott Simpson
fonte
2

Fiz um GIST com Bootstrap 3 dentro de uma classe chamada .bootstrap-wrapper https://gist.github.com/onigetoc/20c4c3933cabd8672e3e

Comecei com esta ferramenta: http://www.css-prefix.com/ E conserte o resto com pesquisar e substituir no PHPstorm. Todas as fontes @ font-face são hospedadas no maxcdn.

Exemplo de primeira linha

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

O namespacing quebra o div de pano de fundo do plugin Modal, uma vez que ele sempre é adicionado diretamente à tag <body>, ignorando o seu elemento de namespacing que tem os estilos aplicados a ele.

Você pode corrigir isso alterando a referência do plug-in para $bodyantes de mostrar o pano de fundo:

myDialog.modal({
    show: false
});

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

myDialog.modal("show");

A $bodypropriedade decide onde o cenário será adicionado.

então cara de pau
fonte
2

Para explicar melhor todos os passos de que Andrew falava para quem não sabe o que é Less. Aqui está um link que explica muito bem como isso é feito passo a passo. Como isolar Bootstrap ou outras bibliotecas CSS

eKelvin
fonte
1

Solução mais simples - comece a usar classes css isoladas de construção personalizadas para Bootstrap.

Por exemplo, para Bootstrap 4.1 baixe arquivos do diretório css4.1 -

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

e envolva seu HTML em um div com a classe bootstrapiso:

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

O modelo de página com bootstrap 4 isolado será

<!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
fonte
0

Eu enfrentei o mesmo problema e método proposto por @Andrew infelizmente não ajudou no meu caso específico. As classes de bootstrap colidiram com as classes de outro framework. É assim que este projeto foi iniciado https://github.com/sneas/bootstrap-sass-namespace . Sinta-se à vontade para usar.

Sneas
fonte
0

Como uma nota adicional para todos. Para fazer os modais funcionarem com um pano de fundo, você pode simplesmente copiar esses estilos do 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
fonte
0

Primeiro clone bootstrap do github:

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

Requisitos de instalação:

npm install

Abra scss / bootstrap.scss e adicione seu namespace:

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

Compilar bootstrap:

npm run dist

Abra dist/css/bootstrap.csse remova o namespace da tag htmle body.

Depois copie o conteúdo da pasta dist para o seu projeto e está tudo pronto.

Diverta-se!

Tobias Ernst
fonte