47

如何将 Bootstrap 限制在 div 的范围内?我需要在 ExtJS 应用程序中为特定的 div 嵌套 Bootstrap 样式表,并且两者都发生冲突,因为它们需要自己的 body、ul、li、a 等。

我试图避免手动编辑 bootstrap.css(或将其保持在最低限度),以便可以轻松更新它。

4

9 回答 9

54

您可以分叉引导存储库并更改bootstrap.less以包装引导样式:

.bootstrap-scope {
    //put bootstrap @includes in here
}

然后,在 bootstrap 项目的根目录下,运行make生成bootstrap.css文件。

您将丢失引导程序分配给 body 和 html 标记的全局样式,但您可能不想要它们。

然后,在您的应用程序中,提供您想要的.bootstrap-scope类的容器。

于 2013-01-03T19:10:33.777 回答
17

由于修改 less/bootstrap.less 的结果对我来说不够好(请参阅帖子底部的原因),我最终过滤了 bootstrap.css :

var css = require('css'), fs = require('fs');

var prefix = '.bootstrap-scope';
var inFile = 'bootstrap.css';

var cssAst = css.parse(fs.readFileSync(inFile, 'utf8'));
prefixNode(cssAst);
console.log(css.stringify(cssAst));

function prefixSelector(sel){
    if (sel.match(/^@/)) return sel;
    var m = sel.match(/(^| )(body|html)($|\W.*)/i);
    if (m) 
        return m[1] + prefix + m[3];
    else
        return prefix + ' ' + sel;
}

function prefixNode(node) {
    if (node.selectors) {
        node.selectors = node.selectors.map(prefixSelector);
    } else if (node.stylesheet) {
        node.stylesheet.rules.forEach(prefixNode);
    } else if (node.rules) {
        node.rules.forEach(prefixNode);
    }
}

既然生成了 bootstrap.css ,也可以盲目地去做(解决方案类似于 Alexey 的,但也处理了一些极端情况):

perl -lpe 'BEGIN { $prefix = ".bootstrap-scope" } if (($indent, $s, $sep) = /^(\s*)([^@\s].*?)(\s*[,{])$/) { $s =~ /^(from|to)*$/ or $s =~ s/(^| )(body|html)($|\W.*)/$1$prefix$3/i or $s = "$prefix $s"; $_ = "$indent$s$sep" }' bootstrap.css

至于修改 less/bootstrap.css 并调用 grunt 来生成 dist/css/bootstrap.css (Andrew Homeyer 的解决方案),在某些情况下似乎效果不佳(至少在 bootstrap 3 中):

  • 像 .make-grid-columns (来自 less/mixins.xml)这样的各种 mixin 最终会被错误地添加前缀。例子:

    .bootstrap-scope .col-sm-1,
      .col-sm-2,
      .col-sm-3,
    
  • LESS中“&”的使用是有限的:

    .caret {
      .btn-default & {
    

    变成

     .btn-default .bootstrap-scope .caret {
    

    而不是我们想要的:

     .bootstrap-scope .btn-default .caret {
    
于 2013-11-18T15:35:49.847 回答
11

如果您有以下文件结构:

  • mystyles.less
  • 我的样式.css
  • /引导程序/
    • 无引导程序
    • 引导程序.css
    • 无网格
    • ...
    • /混合/

而且你想限制引导的范围,你必须把你的 mystyles.less (正确的方式):

.your-class-to-limit-bootstrap-scope{
    @import (less) "bootstrap/bootstrap.css";
}

我们必须导入 bootstrap.css 文件而不是 bootstrap.less,但使用 (less) @import 选项将文件视为 Less 文件,无论文件扩展名是什么。因此,您将获得正确的 css,例如:

.your-class-to-limit-bootstrap-scope .col-xs-1,
.your-class-to-limit-bootstrap-scope  .col-sm-1,
.your-class-to-limit-bootstrap-scope ...
.your-class-to-limit-bootstrap-scope .col-lg-12 {
    position: relative;
    min-height: 1px;
    padding-left: 7px;
    padding-right: 7px;
 }

但是,如果您导入较少的引导文件,您将得到一个范围不正确的 css (错误的方式)

.your-class-to-limit-bootstrap-scope{
    @import "bootstrap/bootstrap.less";
}

因此,您将获得不正确的作用域 css,例如:

.your-class-to-limit-bootstrap-scope .col-xs-1, 
.col-sm-1,
.col-md-1,
...
.col-lg-12 {
    position: relative;
    min-height: 1px;
    padding-left: 15px;
    padding-right: 15px;
}
于 2015-06-04T10:46:14.117 回答
8

有一种更简单的方法可以实现这一合法要求:将 }NEWLINE 和 ,NEWLINE 替换为以前的值和您的类范围。很容易进入例如 Sublime:

  • 选择 }\r\n

  • Alt + F3(选择所有匹配项)

  • 替换为 }\r\n.bootstrap-scope

  • 选择 ,\r\n

  • Alt + F3(选择所有匹配项)

  • 替换为 ,\r\n.bootstrap-scope

就是这样!由于更换大约需要一分钟,因此后续更新将非常容易。希望我的回答有所帮助。

于 2013-05-30T12:51:53.213 回答
5

扩展@Andrew Homeyer 答案:

通过执行以下操作,我在我的 Reactjs 应用程序中获得了 boostrap 的范围样式:

  1. 这里下载引导源
  2. 按照此处的指南安装 grunt。概括:

Bootstrap 使用 Grunt 作为其构建系统,并提供了使用框架的便捷方法。这就是我们编译代码、运行测试等的方式。

安装 Grunt:要安装 Grunt,您必须首先下载并安装 node.js(包括 npm)。npm 代表 node packaged modules,是一种通过 node.js 管理开发依赖的方法。

然后,从命令行:使用 .grunt-cli 全局安装 npm install -g grunt-cli。导航到根 /bootstrap/ 目录,然后运行npm install​​. npm 将查看 package.json 文件并自动安装其中列出的必要本地依赖项。完成后,您将能够运行从命令行提供的各种 Grunt 命令。

  1. less/bootstrap.less将下载源中的文件编辑为以下内容:

.bootstrap-scope {...pasted all @imports here...}

在此处输入图像描述

  1. grunt dist运行并将新的 dist 文件夹复制到我的App.js项目
    import './styling/bootstrap/css/bootstrap.min.css';

在此处输入图像描述

类似的讨论在这里

于 2017-09-26T20:25:39.453 回答
3

无需分叉/编辑原始引导程序。只需像这样将其导入包装在您的文件中(在我的情况下为 sass):我创建了文件“bootstrap-scope-limit.scss”(我在需要引导的地方导入):

.bootstrap-inside {
  @import "~bootstrap-sass/assets/stylesheets/_bootstrap.scss";
  @import "~bootstrap-sass/assets/stylesheets/bootstrap/_theme.scss";
}

重要通知!

请记住,bootstrap 有一些在使用这种方法时不会应用的 body 样式。但是,如果某些动态内容必须使用引导程序,它使您能够通过向元素添加“bootstrap-inside”类来控制引导程序,以启用或禁用整个页面的引导程序。

您应该注意的另一个问题:一些覆盖引导样式的插件可能会出现问题,因为具有新类包装器的引导样式变得更强大(更具体)并且不能被未包装的插件覆盖。


对于 webpack 案例,我建议使用此加载器:https ://www.npmjs.com/package/wrap-css-loader来包装整个包,您可以稍后将其用作应用程序(div?)的一部分

于 2018-04-19T06:36:50.747 回答
0

扩展@jtlindsey 答案。如果你想使用 bootstrap 4,你必须做一些小改动。

而不是编辑less/bootstrap.less,你必须编辑scss/bootstrap.scss

那么你必须按顺序执行这个命令:

gem install bundler
bundle install
npm run dist

并且在 dist 文件夹中生成了新的 bootstrap.min.css。

在这里您可以获得更多信息: https ://getbootstrap.com/docs/4.0/getting-started/build-tools/

于 2018-02-05T13:53:51.887 回答
0

如果你想要一个不涉及外部库的纯 JavaScript 解决方案,你可以走这条路:一般的想法是加载原始 css,然后逐行解析它,在必要时添加你的作用域选择器。

function scopeCSS(scopeSelector, rawCSS) {
  return rawCSS.split('\n').map(line => {
    var trimmedLine = line.trim()
    if (trimmedLine.startsWith('*') || trimmedLine.startsWith('/*') || trimmedLine.startsWith('@media') || trimmedLine === '' || trimmedLine.endsWith(';') || trimmedLine.endsWith('}')) {
      return line
    }
    return line.split(',').map(selector => selector.trim()).map(selector => selector === '' ? selector : `${scopeSelector} ${selector}`).join(',');
  }).join('\n')
}
const rawCSS = document.querySelector('#before').textContent // just as an example, you'd probably use a raw loader with webpack
document.querySelector('#after').textContent = scopeCSS('.bootstrap-scope', rawCSS)
#grid {
  display: grid;
  width: 100%;
  grid-template-columns: 1fr 1fr;
}
<div id="grid">
  <div id="col-1">
    <pre id="before">/*!
 * Bootstrap Grid v5.0.0-alpha1 (https://getbootstrap.com/)
 * Copyright 2011-2020 The Bootstrap Authors
 * Copyright 2011-2020 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
 */
.container,
.container-fluid,
.container-sm,
.container-md,
.container-lg,
.container-xl,
.container-xxl {
  width: 100%;
  padding-right: 1rem;
  padding-left: 1rem;
  margin-right: auto;
  margin-left: auto;
}

@media (min-width: 576px) {
  .container, .container-sm {
    max-width: 540px;
  }
}

@media (min-width: 768px) {
  .container, .container-sm, .container-md {
    max-width: 720px;
  }
}

@media (min-width: 992px) {
  .container, .container-sm, .container-md, .container-lg {
    max-width: 960px;
  }
}

@media (min-width: 1200px) {
  .container, .container-sm, .container-md, .container-lg, .container-xl {
    max-width: 1140px;
  }
}

@media (min-width: 1400px) {
  .container, .container-sm, .container-md, .container-lg, .container-xl, .container-xxl {
    max-width: 1320px;
  }
}

.row {
  --bs-gutter-x: 1.5rem;
  --bs-gutter-y: 0;
  display: flex;
  flex: 1 0 100%;
  flex-wrap: wrap;
  margin-top: calc(var(--bs-gutter-y) * -1);
  margin-right: calc(var(--bs-gutter-x) / -2);
  margin-left: calc(var(--bs-gutter-x) / -2);
}

.row > * {
  box-sizing: border-box;
  flex-shrink: 0;
  width: 100%;
  max-width: 100%;
  padding-right: calc(var(--bs-gutter-x) / 2);
  padding-left: calc(var(--bs-gutter-x) / 2);
  margin-top: var(--bs-gutter-y);
}

.col {
  flex: 1 0 0%;
}
/*# sourceMappingURL=bootstrap-grid.css.map */</pre>
  </div>
  <div id="col-2">
    <pre id="after"></pre>
  </div>
</div>

于 2020-08-25T00:18:59.347 回答
-1

我所知道的唯一肯定比这个脚本更糟糕的是引导程序本身,但这可能仍然是一段时间内最好的答案:

prefix="#bs431"; cat bootstrap.css | while IFS='' read -r line; do if echo "$line" | egrep -i '(\{|,)$' | egrep -iv '\@media' | wc -l | egrep -iq '^0$'; then echo "$line"; else echo "$line" | perl -pe 's/^(\s+)?/\1'"$prefix"' /g' | perl -pe 's/, (\.|#|\[|[a-zA-Z]{1})/, '"$prefix"' \1/g'; fi; done | perl -pe 's/'"$prefix"' :root/'"$prefix"'/g' > bootstrap.scoped.css

于 2019-08-13T19:27:20.273 回答