Cómo crear un espacio de nombres en Twitter Bootstrap para que los estilos no entren en conflicto

106

Quiero usar Twitter Bootstrap, pero solo en elementos específicos, así que necesito encontrar una manera de prefijar todas las clases de Twitter Bootstrap con mi prefijo, o usar menos mixins. Todavía no tengo experiencia con esto, así que no entiendo muy bien cómo hacerlo. Aquí hay un ejemplo del HTML que estoy tratando de diseñar:

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

En este ejemplo, Twitter Bootstrap aplicaría un estilo normal a ambos h1, pero quiero ser más selectivo en las áreas en las que aplico los estilos de Twitter Bootstrap.

Andrés
fuente
Esto ayudaría a "Cómo aislar CSS Bootstrap para evitar conflictos" formden.com/blog/isolate-bootstrap
Samuel Ev

Respuestas:

131

Esto resultó ser más fácil de lo que pensaba. Tanto Less como Sass admiten el espacio de nombres (incluso con la misma sintaxis). Cuando incluye bootstrap, puede hacerlo dentro de un selector para el espacio de nombres:

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

Actualización: para las versiones más recientes de LESS, aquí se explica cómo hacerlo:

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

Aquí se respondió una pregunta similar.

Andrés
fuente
Oye, estoy tratando de seguir esto pero estoy un poco confundido. Estoy trabajando con Angular. Usando CDN, he hecho referencia a bootstrap.min.js, less.min.js y los archivos bootstrap.min.css. Sin embargo, no estoy realmente seguro de dónde hacer el espacio de nombres en mi aplicación.
Batman
Después de hacer esto, mi modal no funciona como también lo usa. ¿Es esto de esperarse?
Batman
2
@Batman No desea utilizar un CDN, porque esencialmente está reescribiendo todo Bootstrap para incluir un prefijo. Necesita usar un preprocesador como SASS para @importel Bootstrap original. También tuve problemas con los modales, creo que porque Bootstrap aplica ciertas clases a la etiqueta del cuerpo de nivel superior. No recuerdo si encontré una solución. Al final, creo que terminé escribiendo mi propio reemplazo modal.
Andrew
4
Esto ya no funciona después de la versión 3 ( hereswhatidid.com/2014/02/… )
adamj
2
¿Alguien puede explicar dónde debe ir esta declaración de importación? Parece un archivo .less independiente. Hice eso y lo puse en la carpeta sin arranque, pero no se compila con el espacio de nombres. Creo que me estoy perdiendo algo
fehays
35

@Andrew gran respuesta. También querrá notar que bootstrap modifica el cuerpo {}, principalmente para agregar fuente. Entonces, cuando lo espacio de nombres a través de LESS / SASS, su archivo css de salida se ve así: (en 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;
}

pero obviamente no habrá una etiqueta de cuerpo dentro de su div, por lo que su contenido de arranque no tendrá la fuente de arranque (ya que todo el arranque hereda la fuente del padre)

Para solucionarlo, la respuesta debería 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
fuente
Te olvidastemargin: 0;
kolobok
1
¡Atención! No sé por qué, pero menos generado en algunos lugares css como .my-prefix .my-prefix ..., por lo que también debe buscarlo y reemplazarlo.
kolobok
10

Poniendo las respuestas de @Andrew, @Kevin y @ adamj juntas (más algunos otros estilos), si incluye lo siguiente en un archivo llamado "bootstrap-namespaced.less", simplemente puede importar 'bootstrap-namespaced.less' en cualquier menos expediente:

// 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;
}
Singularidad
fuente
1
Gracias. Realmente es la mejor solución.
kolobok
Funciona perfectamente !
Kévin Berthommier
8

Agregar un espacio de nombres a bootstrap CSS romperá la funcionalidad modal ya que el bootstrap agrega una clase 'modal-backdrop' directamente al cuerpo. Una solución alternativa es mover este elemento después de abrir el modal, por ejemplo:

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

Puede eliminar el elemento en un controlador para el evento 'hide.bs.modal'.

usuario3567343
fuente
Si está utilizando angular con ngbootstrap, puede elegir abrir el modal dentro de un contenedor específico. this.modalService.open('myModal', {container: '#modalgoeshere'})
Ena
3

Utilice la versión .less de los archivos. Determine qué menos archivos necesita, luego envuelva esos archivos .less con:

.bootstrap-styles {

    h1 { }

}

Esto le dará el resultado de:

.bootstrap-styles h1 { }
Scott Simpson
fuente
2

Hice un GIST con Bootstrap 3, todo dentro de una clase llamada .bootstrap-wrapper https://gist.github.com/onigetoc/20c4c3933cabd8672e3e

Comencé con esta herramienta: http://www.css-prefix.com/ Y arreglé el resto con buscar y reemplazar en PHPstorm. Todas las fuentes @ font-face están alojadas en maxcdn.

Ejemplo de primera línea

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

El espacio de nombres rompe el div de fondo del complemento Modal, ya que siempre se agrega directamente a la etiqueta <body>, omitiendo el elemento de espacio de nombres que tiene los estilos aplicados.

Puede solucionar esto cambiando la referencia del complemento a $bodyantes de que muestre el fondo:

myDialog.modal({
    show: false
});

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

myDialog.modal("show");

La $bodypropiedad decide dónde se agregará el telón de fondo.

entoncesickdude
fuente
1

La solución más simple: comience a usar clases CSS aisladas de compilación personalizada para Bootstrap.

Por ejemplo, para Bootstrap 4.1, descargue archivos del directorio css4.1 -

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

y envuelva su HTML en un div con la clase bootstrapiso:

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

La plantilla de página con bootstrap 4 aislado 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>
usuario3879851
fuente
0

Enfrenté el mismo problema y el método propuesto por @Andrew desafortunadamente no ayudó en mi caso específico. Las clases de Bootstrap chocaron con las clases de otro marco. Así es como se ha iniciado este proyecto https://github.com/sneas/bootstrap-sass-namespace . Siéntete libre de usar.

sneas
fuente
0

Como nota adicional para todos. Para que los modales funcionen con un fondo, simplemente puede copiar estos estilos desde 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
fuente
0

Primer clon bootstrap de github:

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

Requisitos de instalación:

npm install

Abra scss / bootstrap.scss y agregue su espacio de nombres:

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

Compilar bootstrap:

npm run dist

Abra dist/css/bootstrap.cssy elimine el espacio de nombres de la etiqueta htmly body.

Luego copie el contenido de la carpeta dist en su proyecto y estará listo.

¡Que te diviertas!

Tobias Ernst
fuente